mirror of
https://github.com/databasus/databasus.git
synced 2026-04-06 00:32:03 +02:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
880b635827 | ||
|
|
67c14cfa89 | ||
|
|
428a87ae84 | ||
|
|
1f1e22e69c | ||
|
|
c325d42b89 | ||
|
|
04a19cead1 | ||
|
|
648c315312 | ||
|
|
3a205c2f1d | ||
|
|
49ebb01ffd | ||
|
|
e957fb67dd | ||
|
|
7cda83122a | ||
|
|
11195d9078 | ||
|
|
64d7a12f9f | ||
|
|
9853ac425a | ||
|
|
6ad38228ce | ||
|
|
7d576b50a9 | ||
|
|
db3bd98425 | ||
|
|
7d8d0846cb | ||
|
|
05540a8d8d | ||
|
|
8250db9ce5 | ||
|
|
1e8cc46672 | ||
|
|
9d30406d83 | ||
|
|
22e9c605da | ||
|
|
60fe0322f1 | ||
|
|
0ab734f947 | ||
|
|
908fe337d4 | ||
|
|
2364b78e18 | ||
|
|
94fe41f66f | ||
|
|
91ad57c003 | ||
|
|
4e208a2586 | ||
|
|
36686c5d11 | ||
|
|
63e06acfbe | ||
|
|
b44ce1f3ea | ||
|
|
24c97a7070 | ||
|
|
884070a77c | ||
|
|
11891ddbbf | ||
|
|
5ba2c7dc37 | ||
|
|
a888d02aed | ||
|
|
e41f58d63b | ||
|
|
c04ab37962 | ||
|
|
c0756cdcd3 | ||
|
|
54a6a30024 | ||
|
|
8c00801feb |
@@ -21,6 +21,7 @@ backend/*.exe
|
||||
# Scripts and data directories
|
||||
scripts
|
||||
postgresus-data
|
||||
databasus-data
|
||||
|
||||
# IDE and editor files
|
||||
.idea
|
||||
|
||||
12
.github/CODE_OF_CONDUCT.md
vendored
12
.github/CODE_OF_CONDUCT.md
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors and maintainers pledge to make participation in the Postgresus community a friendly and welcoming experience for everyone, regardless of background, experience level or personal circumstances.
|
||||
We as members, contributors and maintainers pledge to make participation in the Databasus community a friendly and welcoming experience for everyone, regardless of background, experience level or personal circumstances.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive and healthy community.
|
||||
|
||||
@@ -31,10 +31,10 @@ We pledge to act and interact in ways that contribute to an open, welcoming, div
|
||||
This Code of Conduct applies within all community spaces, including:
|
||||
|
||||
- GitHub repositories (issues, pull requests, discussions, comments)
|
||||
- Telegram channels and direct messages related to Postgresus
|
||||
- Telegram channels and direct messages related to Databasus
|
||||
- Social media interactions when representing the project
|
||||
- Community forums and online discussions
|
||||
- Any other spaces where Postgresus community members interact
|
||||
- Any other spaces where Databasus community members interact
|
||||
|
||||
This Code of Conduct also applies when an individual is officially representing the community in public spaces, such as using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
@@ -42,7 +42,7 @@ This Code of Conduct also applies when an individual is officially representing
|
||||
|
||||
Instances of abusive or unacceptable behavior may be reported to the community leaders responsible for enforcement:
|
||||
|
||||
- **Email**: [info@postgresus.com](mailto:info@postgresus.com)
|
||||
- **Email**: [info@databasus.com](mailto:info@databasus.com)
|
||||
- **Telegram**: [@rostislav_dugin](https://t.me/rostislav_dugin)
|
||||
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
@@ -79,13 +79,13 @@ Community leaders will follow these Community Impact Guidelines in determining t
|
||||
|
||||
## Contributing with Respect
|
||||
|
||||
When contributing to Postgresus, please:
|
||||
When contributing to Databasus, please:
|
||||
|
||||
- Be patient with maintainers and other contributors
|
||||
- Understand that everyone has different levels of experience
|
||||
- Ask questions in a respectful manner
|
||||
- Accept that your contribution may not be accepted, and be open to feedback
|
||||
- Follow the [contribution guidelines](https://postgresus.com/contribute)
|
||||
- Follow the [contribution guidelines](https://databasus.com/contribute)
|
||||
|
||||
For code contributions, remember to:
|
||||
|
||||
|
||||
28
.github/SECURITY.md
vendored
28
.github/SECURITY.md
vendored
@@ -2,13 +2,13 @@
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability in Postgresus, please report it responsibly. **Do not create a public GitHub issue for security vulnerabilities.**
|
||||
If you discover a security vulnerability in Databasus, please report it responsibly. **Do not create a public GitHub issue for security vulnerabilities.**
|
||||
|
||||
### How to Report
|
||||
|
||||
1. **Email** (preferred): Send details to [info@postgresus.com](mailto:info@postgresus.com)
|
||||
1. **Email** (preferred): Send details to [info@databasus.com](mailto:info@databasus.com)
|
||||
2. **Telegram**: Contact [@rostislav_dugin](https://t.me/rostislav_dugin)
|
||||
3. **GitHub Security Advisories**: Use the [private vulnerability reporting](https://github.com/RostislavDugin/postgresus/security/advisories/new) feature
|
||||
3. **GitHub Security Advisories**: Use the [private vulnerability reporting](https://github.com/databasus/databasus/security/advisories/new) feature
|
||||
|
||||
### What to Include
|
||||
|
||||
@@ -23,11 +23,23 @@ If you discover a security vulnerability in Postgresus, please report it respons
|
||||
| ------- | --------- |
|
||||
| Latest | Yes |
|
||||
|
||||
We recommend always using the latest version of Postgresus. Security patches are applied to the most recent release.
|
||||
We recommend always using the latest version of Databasus. Security patches are applied to the most recent release.
|
||||
|
||||
### PostgreSQL Compatibility
|
||||
|
||||
Postgresus supports PostgreSQL versions 12, 13, 14, 15, 16, 17 and 18.
|
||||
Databasus supports PostgreSQL versions 12, 13, 14, 15, 16, 17 and 18.
|
||||
|
||||
### MySQL Compatibility
|
||||
|
||||
Databasus supports MySQL versions 5.7, 8 and 9.
|
||||
|
||||
### MariaDB Compatibility
|
||||
|
||||
Databasus supports MariaDB versions 10 and 11.
|
||||
|
||||
### MongoDB Compatibility
|
||||
|
||||
Databasus supports MongoDB versions 4, 5, 6, 7 and 8.
|
||||
|
||||
## Response Timeline
|
||||
|
||||
@@ -39,16 +51,16 @@ We follow a coordinated disclosure policy. We ask that you give us reasonable ti
|
||||
|
||||
## Security Features
|
||||
|
||||
Postgresus is designed with security in mind. For full details, see our [security documentation](https://postgresus.com/security).
|
||||
Databasus is designed with security in mind. For full details, see our [security documentation](https://databasus.com/security).
|
||||
|
||||
Key features include:
|
||||
|
||||
- **AES-256-GCM Encryption**: Enterprise-grade encryption for backup files and sensitive data
|
||||
- **Read-Only Database Access**: Postgresus uses read-only access by default and warns if write permissions are detected
|
||||
- **Read-Only Database Access**: Databasus uses read-only access by default and warns if write permissions are detected
|
||||
- **Role-Based Access Control**: Assign viewer, member, admin or owner roles within workspaces
|
||||
- **Audit Logging**: Track all system activities and changes made by users
|
||||
- **Zero-Trust Storage**: Encrypted backups are safe even in shared cloud storage
|
||||
|
||||
## License
|
||||
|
||||
Postgresus is licensed under [Apache 2.0](../LICENSE).
|
||||
Databasus is licensed under [Apache 2.0](../LICENSE).
|
||||
37
.github/workflows/ci-release.yml
vendored
37
.github/workflows/ci-release.yml
vendored
@@ -151,17 +151,17 @@ jobs:
|
||||
cd backend
|
||||
cat > .env << EOF
|
||||
# docker-compose.yml
|
||||
DEV_DB_NAME=postgresus
|
||||
DEV_DB_NAME=databasus
|
||||
DEV_DB_USERNAME=postgres
|
||||
DEV_DB_PASSWORD=Q1234567
|
||||
#app
|
||||
ENV_MODE=development
|
||||
# db
|
||||
DATABASE_DSN=host=localhost user=postgres password=Q1234567 dbname=postgresus port=5437 sslmode=disable
|
||||
DATABASE_URL=postgres://postgres:Q1234567@localhost:5437/postgresus?sslmode=disable
|
||||
DATABASE_DSN=host=localhost user=postgres password=Q1234567 dbname=databasus port=5437 sslmode=disable
|
||||
DATABASE_URL=postgres://postgres:Q1234567@localhost:5437/databasus?sslmode=disable
|
||||
# migrations
|
||||
GOOSE_DRIVER=postgres
|
||||
GOOSE_DBSTRING=postgres://postgres:Q1234567@localhost:5437/postgresus?sslmode=disable
|
||||
GOOSE_DBSTRING=postgres://postgres:Q1234567@localhost:5437/databasus?sslmode=disable
|
||||
GOOSE_MIGRATION_DIR=./migrations
|
||||
# testing
|
||||
# to get Google Drive env variables: add storage in UI and copy data from added storage here
|
||||
@@ -191,6 +191,7 @@ jobs:
|
||||
TEST_MYSQL_57_PORT=33057
|
||||
TEST_MYSQL_80_PORT=33080
|
||||
TEST_MYSQL_84_PORT=33084
|
||||
TEST_MYSQL_90_PORT=33090
|
||||
# testing MariaDB
|
||||
TEST_MARIADB_55_PORT=33055
|
||||
TEST_MARIADB_101_PORT=33101
|
||||
@@ -219,7 +220,7 @@ jobs:
|
||||
TEST_MONGODB_50_PORT=27050
|
||||
TEST_MONGODB_60_PORT=27060
|
||||
TEST_MONGODB_70_PORT=27070
|
||||
TEST_MONGODB_80_PORT=27080
|
||||
TEST_MONGODB_82_PORT=27082
|
||||
EOF
|
||||
|
||||
- name: Start test containers
|
||||
@@ -259,6 +260,8 @@ jobs:
|
||||
timeout 120 bash -c 'until docker exec test-mysql-80 mysqladmin ping -h localhost -u root -prootpassword --silent 2>/dev/null; do sleep 2; done'
|
||||
echo "Waiting for MySQL 8.4..."
|
||||
timeout 120 bash -c 'until docker exec test-mysql-84 mysqladmin ping -h localhost -u root -prootpassword --silent 2>/dev/null; do sleep 2; done'
|
||||
echo "Waiting for MySQL 9.0..."
|
||||
timeout 120 bash -c 'until docker exec test-mysql-90 mysqladmin ping -h localhost -u root -prootpassword --silent 2>/dev/null; do sleep 2; done'
|
||||
|
||||
# Wait for MariaDB containers
|
||||
echo "Waiting for MariaDB 5.5..."
|
||||
@@ -297,15 +300,15 @@ jobs:
|
||||
timeout 120 bash -c 'until docker exec test-mongodb-60 mongosh --eval "db.adminCommand(\"ping\")" -u root -p rootpassword --authenticationDatabase admin 2>/dev/null; do sleep 2; done'
|
||||
echo "Waiting for MongoDB 7.0..."
|
||||
timeout 120 bash -c 'until docker exec test-mongodb-70 mongosh --eval "db.adminCommand(\"ping\")" -u root -p rootpassword --authenticationDatabase admin 2>/dev/null; do sleep 2; done'
|
||||
echo "Waiting for MongoDB 8.0..."
|
||||
timeout 120 bash -c 'until docker exec test-mongodb-80 mongosh --eval "db.adminCommand(\"ping\")" -u root -p rootpassword --authenticationDatabase admin 2>/dev/null; do sleep 2; done'
|
||||
echo "Waiting for MongoDB 8.2..."
|
||||
timeout 120 bash -c 'until docker exec test-mongodb-82 mongosh --eval "db.adminCommand(\"ping\")" -u root -p rootpassword --authenticationDatabase admin 2>/dev/null; do sleep 2; done'
|
||||
|
||||
- name: Create data and temp directories
|
||||
run: |
|
||||
# Create directories that are used for backups and restore
|
||||
# These paths match what's configured in config.go
|
||||
mkdir -p postgresus-data/backups
|
||||
mkdir -p postgresus-data/temp
|
||||
mkdir -p databasus-data/backups
|
||||
mkdir -p databasus-data/temp
|
||||
|
||||
- name: Cache PostgreSQL client tools
|
||||
id: cache-postgres
|
||||
@@ -319,7 +322,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: backend/tools/mysql
|
||||
key: mysql-clients-57-80-84-v1
|
||||
key: mysql-clients-57-80-84-9-v1
|
||||
|
||||
- name: Cache MariaDB client tools
|
||||
id: cache-mariadb
|
||||
@@ -536,8 +539,8 @@ jobs:
|
||||
build-args: |
|
||||
APP_VERSION=dev-${{ github.sha }}
|
||||
tags: |
|
||||
rostislavdugin/postgresus:latest
|
||||
rostislavdugin/postgresus:${{ github.sha }}
|
||||
databasus/databasus:latest
|
||||
databasus/databasus:${{ github.sha }}
|
||||
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -570,9 +573,9 @@ jobs:
|
||||
build-args: |
|
||||
APP_VERSION=${{ needs.determine-version.outputs.new_version }}
|
||||
tags: |
|
||||
rostislavdugin/postgresus:latest
|
||||
rostislavdugin/postgresus:v${{ needs.determine-version.outputs.new_version }}
|
||||
rostislavdugin/postgresus:${{ github.sha }}
|
||||
databasus/databasus:latest
|
||||
databasus/databasus:v${{ needs.determine-version.outputs.new_version }}
|
||||
databasus/databasus:${{ github.sha }}
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -659,7 +662,7 @@ jobs:
|
||||
|
||||
# Add Docker image info
|
||||
CHANGELOG="${CHANGELOG}### 🐳 Docker\n"
|
||||
CHANGELOG="${CHANGELOG}- **Image**: \`rostislavdugin/postgresus:v${NEW_VERSION}\`\n"
|
||||
CHANGELOG="${CHANGELOG}- **Image**: \`databasus/databasus:v${NEW_VERSION}\`\n"
|
||||
CHANGELOG="${CHANGELOG}- **Platforms**: linux/amd64, linux/arm64\n\n"
|
||||
|
||||
# Set output for GitHub release
|
||||
@@ -723,4 +726,4 @@ jobs:
|
||||
- name: Push Helm chart to GHCR
|
||||
run: |
|
||||
VERSION="${{ needs.determine-version.outputs.new_version }}"
|
||||
helm push postgresus-${VERSION}.tgz oci://ghcr.io/rostislavdugin/charts
|
||||
helm push databasus-${VERSION}.tgz oci://ghcr.io/databasus/charts
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
postgresus_data/
|
||||
postgresus-data/
|
||||
databasus-data/
|
||||
.env
|
||||
pgdata/
|
||||
docker-compose.yml
|
||||
|
||||
15
CITATION.cff
15
CITATION.cff
@@ -1,13 +1,13 @@
|
||||
cff-version: 1.2.0
|
||||
title: Postgresus
|
||||
title: Databasus
|
||||
message: "If you use this software, please cite it as below."
|
||||
type: software
|
||||
authors:
|
||||
- family-names: Dugin
|
||||
given-names: Rostislav
|
||||
repository-code: https://github.com/RostislavDugin/postgresus
|
||||
url: https://postgresus.com
|
||||
abstract: "Free, open source and self-hosted solution for automated PostgreSQL backups with multiple storage options and notifications."
|
||||
repository-code: https://github.com/databasus/databasus
|
||||
url: https://databasus.com
|
||||
abstract: "Free, open source and self-hosted solution for automated databases backups with multiple storage options and notifications."
|
||||
keywords:
|
||||
- docker
|
||||
- kubernetes
|
||||
@@ -28,6 +28,9 @@ keywords:
|
||||
- pg
|
||||
- system-administration
|
||||
- database-backup
|
||||
- mysql
|
||||
- mongodb
|
||||
- mariadb
|
||||
license: Apache-2.0
|
||||
version: 2.13.0
|
||||
date-released: "2025-12-21"
|
||||
version: 2.18.4
|
||||
date-released: "2025-12-30"
|
||||
|
||||
134
Dockerfile
134
Dockerfile
@@ -80,7 +80,7 @@ ENV ENV_MODE=production
|
||||
# ========= STEP 1: Install base packages =========
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
wget ca-certificates gnupg lsb-release sudo gosu curl unzip xz-utils libncurses5
|
||||
wget ca-certificates gnupg lsb-release sudo gosu curl unzip xz-utils libncurses5 libncurses6
|
||||
RUN rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ========= Install PostgreSQL client binaries (versions 12-18) =========
|
||||
@@ -130,10 +130,11 @@ RUN apt-get update && \
|
||||
|
||||
# Create directories for all database clients
|
||||
RUN mkdir -p /usr/local/mysql-5.7/bin /usr/local/mysql-8.0/bin /usr/local/mysql-8.4/bin \
|
||||
/usr/local/mysql-9/bin \
|
||||
/usr/local/mariadb-10.6/bin /usr/local/mariadb-12.1/bin \
|
||||
/usr/local/mongodb-database-tools/bin
|
||||
|
||||
# ========= Install MySQL clients (5.7, 8.0, 8.4) =========
|
||||
# ========= Install MySQL clients (5.7, 8.0, 8.4, 9) =========
|
||||
# Pre-downloaded binaries from assets/tools/ - no network download needed
|
||||
# Note: MySQL 5.7 is only available for x86_64
|
||||
# Note: MySQL binaries require libncurses5 for terminal handling
|
||||
@@ -142,11 +143,13 @@ COPY assets/tools/arm/mysql/ /tmp/mysql-arm/
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
||||
cp /tmp/mysql-x64/mysql-5.7/bin/* /usr/local/mysql-5.7/bin/ && \
|
||||
cp /tmp/mysql-x64/mysql-8.0/bin/* /usr/local/mysql-8.0/bin/ && \
|
||||
cp /tmp/mysql-x64/mysql-8.4/bin/* /usr/local/mysql-8.4/bin/; \
|
||||
cp /tmp/mysql-x64/mysql-8.4/bin/* /usr/local/mysql-8.4/bin/ && \
|
||||
cp /tmp/mysql-x64/mysql-9/bin/* /usr/local/mysql-9/bin/; \
|
||||
elif [ "$TARGETARCH" = "arm64" ]; then \
|
||||
echo "MySQL 5.7 not available for arm64, skipping..." && \
|
||||
cp /tmp/mysql-arm/mysql-8.0/bin/* /usr/local/mysql-8.0/bin/ && \
|
||||
cp /tmp/mysql-arm/mysql-8.4/bin/* /usr/local/mysql-8.4/bin/; \
|
||||
cp /tmp/mysql-arm/mysql-8.4/bin/* /usr/local/mysql-8.4/bin/ && \
|
||||
cp /tmp/mysql-arm/mysql-9/bin/* /usr/local/mysql-9/bin/; \
|
||||
fi && \
|
||||
rm -rf /tmp/mysql-x64 /tmp/mysql-arm && \
|
||||
chmod +x /usr/local/mysql-*/bin/*
|
||||
@@ -185,8 +188,8 @@ RUN apt-get update && \
|
||||
|
||||
# Create postgres user and set up directories
|
||||
RUN useradd -m -s /bin/bash postgres || true && \
|
||||
mkdir -p /postgresus-data/pgdata && \
|
||||
chown -R postgres:postgres /postgresus-data/pgdata
|
||||
mkdir -p /databasus-data/pgdata && \
|
||||
chown -R postgres:postgres /databasus-data/pgdata
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -215,59 +218,120 @@ COPY <<EOF /app/start.sh
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Check for legacy postgresus-data volume mount
|
||||
if [ -d "/postgresus-data" ] && [ "\$(ls -A /postgresus-data 2>/dev/null)" ]; then
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "ERROR: Legacy volume detected!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "You are using the \`postgresus-data\` folder. It seems you changed the image name from Postgresus to Databasus without changing the volume."
|
||||
echo ""
|
||||
echo "Please either:"
|
||||
echo " 1. Switch back to image rostislavdugin/postgresus:latest (supported until ~Dec 2026)"
|
||||
echo " 2. Read the migration guide: https://databasus.com/installation/#postgresus-migration"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# PostgreSQL 17 binary paths
|
||||
PG_BIN="/usr/lib/postgresql/17/bin"
|
||||
|
||||
# Ensure proper ownership of data directory
|
||||
echo "Setting up data directory permissions..."
|
||||
mkdir -p /postgresus-data/pgdata
|
||||
chown -R postgres:postgres /postgresus-data
|
||||
mkdir -p /databasus-data/pgdata
|
||||
chown -R postgres:postgres /databasus-data
|
||||
|
||||
# Initialize PostgreSQL if not already initialized
|
||||
if [ ! -s "/postgresus-data/pgdata/PG_VERSION" ]; then
|
||||
if [ ! -s "/databasus-data/pgdata/PG_VERSION" ]; then
|
||||
echo "Initializing PostgreSQL database..."
|
||||
gosu postgres \$PG_BIN/initdb -D /postgresus-data/pgdata --encoding=UTF8 --locale=C.UTF-8
|
||||
gosu postgres \$PG_BIN/initdb -D /databasus-data/pgdata --encoding=UTF8 --locale=C.UTF-8
|
||||
|
||||
# Configure PostgreSQL
|
||||
echo "host all all 127.0.0.1/32 md5" >> /postgresus-data/pgdata/pg_hba.conf
|
||||
echo "local all all trust" >> /postgresus-data/pgdata/pg_hba.conf
|
||||
echo "port = 5437" >> /postgresus-data/pgdata/postgresql.conf
|
||||
echo "listen_addresses = 'localhost'" >> /postgresus-data/pgdata/postgresql.conf
|
||||
echo "shared_buffers = 256MB" >> /postgresus-data/pgdata/postgresql.conf
|
||||
echo "max_connections = 100" >> /postgresus-data/pgdata/postgresql.conf
|
||||
echo "host all all 127.0.0.1/32 md5" >> /databasus-data/pgdata/pg_hba.conf
|
||||
echo "local all all trust" >> /databasus-data/pgdata/pg_hba.conf
|
||||
echo "port = 5437" >> /databasus-data/pgdata/postgresql.conf
|
||||
echo "listen_addresses = 'localhost'" >> /databasus-data/pgdata/postgresql.conf
|
||||
echo "shared_buffers = 256MB" >> /databasus-data/pgdata/postgresql.conf
|
||||
echo "max_connections = 100" >> /databasus-data/pgdata/postgresql.conf
|
||||
fi
|
||||
|
||||
# Start PostgreSQL in background
|
||||
echo "Starting PostgreSQL..."
|
||||
gosu postgres \$PG_BIN/postgres -D /postgresus-data/pgdata -p 5437 &
|
||||
POSTGRES_PID=\$!
|
||||
# Function to start PostgreSQL and wait for it to be ready
|
||||
start_postgres() {
|
||||
echo "Starting PostgreSQL..."
|
||||
gosu postgres \$PG_BIN/postgres -D /databasus-data/pgdata -p 5437 &
|
||||
POSTGRES_PID=\$!
|
||||
|
||||
echo "Waiting for PostgreSQL to be ready..."
|
||||
for i in {1..30}; do
|
||||
if gosu postgres \$PG_BIN/pg_isready -p 5437 -h localhost >/dev/null 2>&1; then
|
||||
echo "PostgreSQL is ready!"
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "Waiting for PostgreSQL to be ready..."
|
||||
for i in {1..30}; do
|
||||
if gosu postgres \$PG_BIN/pg_isready -p 5437 -h localhost >/dev/null 2>&1; then
|
||||
echo "PostgreSQL is ready!"
|
||||
break
|
||||
fi
|
||||
if [ \$i -eq 30 ]; then
|
||||
echo "PostgreSQL failed to start"
|
||||
# Try to start PostgreSQL
|
||||
if ! start_postgres; then
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "PostgreSQL failed to start. Attempting WAL reset recovery..."
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Kill any remaining postgres processes
|
||||
pkill -9 postgres 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Attempt pg_resetwal to recover from WAL corruption
|
||||
echo "Running pg_resetwal to reset WAL..."
|
||||
if gosu postgres \$PG_BIN/pg_resetwal -f /databasus-data/pgdata; then
|
||||
echo "WAL reset successful. Restarting PostgreSQL..."
|
||||
|
||||
# Try starting PostgreSQL again after WAL reset
|
||||
if start_postgres; then
|
||||
echo "PostgreSQL recovered successfully after WAL reset!"
|
||||
else
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "ERROR: PostgreSQL failed to start even after WAL reset."
|
||||
echo "The database may be severely corrupted."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " 1. Delete the volume and start fresh (data loss)"
|
||||
echo " 2. Manually inspect /databasus-data/pgdata for issues"
|
||||
echo "=========================================="
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "ERROR: pg_resetwal failed."
|
||||
echo "The database may be severely corrupted."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " 1. Delete the volume and start fresh (data loss)"
|
||||
echo " 2. Manually inspect /databasus-data/pgdata for issues"
|
||||
echo "=========================================="
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# Create database and set password for postgres user
|
||||
echo "Setting up database and user..."
|
||||
gosu postgres \$PG_BIN/psql -p 5437 -h localhost -d postgres << 'SQL'
|
||||
ALTER USER postgres WITH PASSWORD 'Q1234567';
|
||||
SELECT 'CREATE DATABASE postgresus OWNER postgres'
|
||||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'postgresus')
|
||||
SELECT 'CREATE DATABASE databasus OWNER postgres'
|
||||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'databasus')
|
||||
\\gexec
|
||||
\\q
|
||||
SQL
|
||||
|
||||
# Start the main application
|
||||
echo "Starting Postgresus application..."
|
||||
echo "Starting Databasus application..."
|
||||
exec ./main
|
||||
EOF
|
||||
|
||||
@@ -276,7 +340,7 @@ RUN chmod +x /app/start.sh
|
||||
EXPOSE 4005
|
||||
|
||||
# Volume for PostgreSQL data
|
||||
VOLUME ["/postgresus-data"]
|
||||
VOLUME ["/databasus-data"]
|
||||
|
||||
ENTRYPOINT ["/app/start.sh"]
|
||||
CMD []
|
||||
2
LICENSE
2
LICENSE
@@ -187,7 +187,7 @@
|
||||
same "license" line as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2025 Postgresus
|
||||
Copyright 2026 Databasus
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
189
README.md
189
README.md
@@ -1,18 +1,21 @@
|
||||
<div align="center">
|
||||
<img src="assets/logo.svg" style="margin-bottom: 20px;" alt="Postgresus Logo" width="250"/>
|
||||
<img src="assets/logo.svg" alt="Databasus Logo" width="250"/>
|
||||
|
||||
<h3>PostgreSQL backup</h3>
|
||||
<p>Free, open source and self-hosted solution for automated PostgreSQL backups. With multiple storage options and notifications</p>
|
||||
<h3>Backup tool for PostgreSQL, MySQL and MongoDB</h3>
|
||||
<p>Databasus is a free, open source and self-hosted tool to backup databases. Make backups with different storages (S3, Google Drive, FTP, etc.) and notifications about progress (Slack, Discord, Telegram, etc.). Previously known as Postgresus (see migration guide).</p>
|
||||
|
||||
<!-- Badges -->
|
||||
[](https://www.postgresql.org/)
|
||||
[](https://www.mysql.com/)
|
||||
[](https://mariadb.org/)
|
||||
[](https://www.mongodb.com/)
|
||||
<br />
|
||||
[](LICENSE)
|
||||
[](https://hub.docker.com/r/rostislavdugin/postgresus)
|
||||
[](https://github.com/RostislavDugin/postgresus)
|
||||
|
||||
[](https://www.postgresql.org/)
|
||||
[](https://github.com/RostislavDugin/postgresus)
|
||||
[](https://github.com/RostislavDugin/postgresus)
|
||||
|
||||
[](https://github.com/databasus/databasus)
|
||||
[](https://github.com/databasus/databasus)
|
||||
[](https://github.com/databasus/databasus)
|
||||
|
||||
<p>
|
||||
<a href="#-features">Features</a> •
|
||||
<a href="#-installation">Installation</a> •
|
||||
@@ -22,12 +25,12 @@
|
||||
</p>
|
||||
|
||||
<p style="margin-top: 20px; margin-bottom: 20px; font-size: 1.2em;">
|
||||
<a href="https://postgresus.com" target="_blank"><strong>🌐 Postgresus website</strong></a>
|
||||
<a href="https://databasus.com" target="_blank"><strong>🌐 Databasus website</strong></a>
|
||||
</p>
|
||||
|
||||
<img src="assets/dashboard-dark.svg" alt="Postgresus Dark Dashboard" width="800" style="margin-bottom: 10px;"/>
|
||||
<img src="assets/dashboard-dark.svg" alt="Databasus Dark Dashboard" width="800" style="margin-bottom: 10px;"/>
|
||||
|
||||
<img src="assets/dashboard.svg" alt="Postgresus Dashboard" width="800"/>
|
||||
<img src="assets/dashboard.svg" alt="Databasus Dashboard" width="800"/>
|
||||
|
||||
|
||||
</div>
|
||||
@@ -36,38 +39,39 @@
|
||||
|
||||
## ✨ Features
|
||||
|
||||
### 💾 **Supported databases**
|
||||
|
||||
- **PostgreSQL**: 12, 13, 14, 15, 16, 17 and 18
|
||||
- **MySQL**: 5.7, 8 and 9
|
||||
- **MariaDB**: 10 and 11
|
||||
- **MongoDB**: 4, 5, 6, 7 and 8
|
||||
|
||||
### 🔄 **Scheduled backups**
|
||||
|
||||
- **Flexible scheduling**: hourly, daily, weekly, monthly or cron
|
||||
- **Precise timing**: run backups at specific times (e.g., 4 AM during low traffic)
|
||||
- **Smart compression**: 4-8x space savings with balanced compression (~20% overhead)
|
||||
|
||||
### 🗄️ **Multiple storage destinations** <a href="https://postgresus.com/storages">(view supported)</a>
|
||||
### 🗄️ **Multiple storage destinations** <a href="https://databasus.com/storages">(view supported)</a>
|
||||
|
||||
- **Local storage**: Keep backups on your VPS/server
|
||||
- **Cloud storage**: S3, Cloudflare R2, Google Drive, NAS, Dropbox, SFTP, Rclone and more
|
||||
- **Secure**: All data stays under your control
|
||||
|
||||
### 📱 **Smart notifications** <a href="https://postgresus.com/notifiers">(view supported)</a>
|
||||
### 📱 **Smart notifications** <a href="https://databasus.com/notifiers">(view supported)</a>
|
||||
|
||||
- **Multiple channels**: Email, Telegram, Slack, Discord, webhooks
|
||||
- **Real-time updates**: Success and failure notifications
|
||||
- **Team integration**: Perfect for DevOps workflows
|
||||
|
||||
### 🐘 **PostgreSQL support**
|
||||
|
||||
- **Multiple versions**: PostgreSQL 12, 13, 14, 15, 16, 17 and 18
|
||||
- **SSL support**: Secure connections available
|
||||
- **Easy restoration**: One-click restore from any backup
|
||||
|
||||
### 🔒 **Enterprise-grade security** <a href="https://postgresus.com/security">(docs)</a>
|
||||
### 🔒 **Enterprise-grade security** <a href="https://databasus.com/security">(docs)</a>
|
||||
|
||||
- **AES-256-GCM encryption**: Enterprise-grade protection for backup files
|
||||
- **Zero-trust storage**: Backups are encrypted and they are useless to attackers, so you can keep them in shared storages like S3, Azure Blob Storage, etc.
|
||||
- **Zero-trust storage**: Backups are encrypted and remain useless to attackers, so you can safely store them in shared storage like S3, Azure Blob Storage, etc.
|
||||
- **Encryption for secrets**: Any sensitive data is encrypted and never exposed, even in logs or error messages
|
||||
- **Read-only user**: Postgresus uses by default a read-only user for backups and never stores anything that can change your data
|
||||
- **Read-only user**: Databasus uses a read-only user by default for backups and never stores anything that can modify your data
|
||||
|
||||
### 👥 **Suitable for teams** <a href="https://postgresus.com/access-management">(docs)</a>
|
||||
### 👥 **Suitable for teams** <a href="https://databasus.com/access-management">(docs)</a>
|
||||
|
||||
- **Workspaces**: Group databases, notifiers and storages for different projects or teams
|
||||
- **Access management**: Control who can view or manage specific databases with role-based permissions
|
||||
@@ -82,11 +86,11 @@
|
||||
|
||||
### ☁️ **Works with self-hosted & cloud databases**
|
||||
|
||||
Postgresus works seamlessly with both self-hosted PostgreSQL and cloud-managed databases:
|
||||
Databasus works seamlessly with both self-hosted PostgreSQL and cloud-managed databases:
|
||||
|
||||
- **Cloud support**: AWS RDS, Google Cloud SQL, Azure Database for PostgreSQL
|
||||
- **Self-hosted**: Any PostgreSQL instance you manage yourself
|
||||
- **Why no PITR?**: Cloud providers already offer native PITR, and external PITR backups cannot be restored to managed cloud databases — making them impractical for cloud-hosted PostgreSQL
|
||||
- **Why no PITR support?**: Cloud providers already offer native PITR, and external PITR backups cannot be restored to managed cloud databases — making them impractical for cloud-hosted PostgreSQL
|
||||
- **Practical granularity**: Hourly and daily backups are sufficient for 99% of projects without the operational complexity of WAL archiving
|
||||
|
||||
### 🐳 **Self-hosted & secure**
|
||||
@@ -95,53 +99,54 @@ Postgresus works seamlessly with both self-hosted PostgreSQL and cloud-managed d
|
||||
- **Privacy-first**: All your data stays on your infrastructure
|
||||
- **Open source**: Apache 2.0 licensed, inspect every line of code
|
||||
|
||||
### 📦 Installation <a href="https://postgresus.com/installation">(docs)</a>
|
||||
### 📦 Installation <a href="https://databasus.com/installation">(docs)</a>
|
||||
|
||||
You have several ways to install Postgresus:
|
||||
You have four ways to install Databasus:
|
||||
|
||||
- Script (recommended)
|
||||
- Automated script (recommended)
|
||||
- Simple Docker run
|
||||
- Docker Compose setup
|
||||
- Kubernetes with Helm
|
||||
|
||||
<img src="assets/healthchecks.svg" alt="Postgresus Dashboard" width="800"/>
|
||||
<img src="assets/healthchecks.svg" alt="Databasus Dashboard" width="800"/>
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
You have three ways to install Postgresus: automated script (recommended), simple Docker run, or Docker Compose setup.
|
||||
You have four ways to install Databasus: automated script (recommended), simple Docker run, or Docker Compose setup.
|
||||
|
||||
### Option 1: Automated installation script (recommended, Linux only)
|
||||
|
||||
The installation script will:
|
||||
|
||||
- ✅ Install Docker with Docker Compose (if not already installed)
|
||||
- ✅ Set up Postgresus
|
||||
- ✅ Set up Databasus
|
||||
- ✅ Configure automatic startup on system reboot
|
||||
|
||||
```bash
|
||||
sudo apt-get install -y curl && \
|
||||
sudo curl -sSL https://raw.githubusercontent.com/RostislavDugin/postgresus/refs/heads/main/install-postgresus.sh \
|
||||
sudo curl -sSL https://raw.githubusercontent.com/databasus/databasus/refs/heads/main/install-databasus.sh \
|
||||
| sudo bash
|
||||
```
|
||||
|
||||
### Option 2: Simple Docker run
|
||||
|
||||
The easiest way to run Postgresus with embedded PostgreSQL:
|
||||
The easiest way to run Databasus:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name postgresus \
|
||||
--name databasus \
|
||||
-p 4005:4005 \
|
||||
-v ./postgresus-data:/postgresus-data \
|
||||
-v ./databasus-data:/databasus-data \
|
||||
--restart unless-stopped \
|
||||
rostislavdugin/postgresus:latest
|
||||
databasus/databasus:latest
|
||||
```
|
||||
|
||||
This single command will:
|
||||
|
||||
- ✅ Start Postgresus
|
||||
- ✅ Store all data in `./postgresus-data` directory
|
||||
- ✅ Start Databasus
|
||||
- ✅ Store all data in `./databasus-data` directory
|
||||
- ✅ Automatically restart on system reboot
|
||||
|
||||
### Option 3: Docker Compose setup
|
||||
@@ -150,13 +155,13 @@ Create a `docker-compose.yml` file with the following configuration:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
postgresus:
|
||||
container_name: postgresus
|
||||
image: rostislavdugin/postgresus:latest
|
||||
databasus:
|
||||
container_name: databasus
|
||||
image: databasus/databasus:latest
|
||||
ports:
|
||||
- "4005:4005"
|
||||
volumes:
|
||||
- ./postgresus-data:/postgresus-data
|
||||
- ./databasus-data:/databasus-data
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
@@ -173,33 +178,33 @@ For Kubernetes deployments, install directly from the OCI registry.
|
||||
**With ClusterIP + port-forward (development/testing):**
|
||||
|
||||
```bash
|
||||
helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus \
|
||||
-n postgresus --create-namespace
|
||||
helm install databasus oci://ghcr.io/databasus/charts/databasus \
|
||||
-n databasus --create-namespace
|
||||
```
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/postgresus-service 4005:4005 -n postgresus
|
||||
kubectl port-forward svc/databasus-service 4005:4005 -n databasus
|
||||
# Access at http://localhost:4005
|
||||
```
|
||||
|
||||
**With LoadBalancer (cloud environments):**
|
||||
|
||||
```bash
|
||||
helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus \
|
||||
-n postgresus --create-namespace \
|
||||
helm install databasus oci://ghcr.io/databasus/charts/databasus \
|
||||
-n databasus --create-namespace \
|
||||
--set service.type=LoadBalancer
|
||||
```
|
||||
|
||||
```bash
|
||||
kubectl get svc postgresus-service -n postgresus
|
||||
kubectl get svc databasus-service -n databasus
|
||||
# Access at http://<EXTERNAL-IP>:4005
|
||||
```
|
||||
|
||||
**With Ingress (domain-based access):**
|
||||
|
||||
```bash
|
||||
helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus \
|
||||
-n postgresus --create-namespace \
|
||||
helm install databasus oci://ghcr.io/databasus/charts/databasus \
|
||||
-n databasus --create-namespace \
|
||||
--set ingress.enabled=true \
|
||||
--set ingress.hosts[0].host=backup.example.com
|
||||
```
|
||||
@@ -211,19 +216,19 @@ For more options (NodePort, TLS, HTTPRoute for Gateway API), see the [Helm chart
|
||||
## 🚀 Usage
|
||||
|
||||
1. **Access the dashboard**: Navigate to `http://localhost:4005`
|
||||
2. **Add first DB for backup**: Click "New Database" and follow the setup wizard
|
||||
2. **Add your first database for backup**: Click "New Database" and follow the setup wizard
|
||||
3. **Configure schedule**: Choose from hourly, daily, weekly, monthly or cron intervals
|
||||
4. **Set database connection**: Enter your PostgreSQL credentials and connection details
|
||||
4. **Set database connection**: Enter your database credentials and connection details
|
||||
5. **Choose storage**: Select where to store your backups (local, S3, Google Drive, etc.)
|
||||
6. **Add notifications** (optional): Configure email, Telegram, Slack, or webhook notifications
|
||||
7. **Save and start**: Postgresus will validate settings and begin the backup schedule
|
||||
7. **Save and start**: Databasus will validate settings and begin the backup schedule
|
||||
|
||||
### 🔑 Resetting password <a href="https://postgresus.com/password">(docs)</a>
|
||||
### 🔑 Resetting password <a href="https://databasus.com/password">(docs)</a>
|
||||
|
||||
If you need to reset the password, you can use the built-in password reset command:
|
||||
|
||||
```bash
|
||||
docker exec -it postgresus ./main --new-password="YourNewSecurePassword123" --email="admin"
|
||||
docker exec -it databasus ./main --new-password="YourNewSecurePassword123" --email="admin"
|
||||
```
|
||||
|
||||
Replace `admin` with the actual email address of the user whose password you want to reset.
|
||||
@@ -238,4 +243,74 @@ This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENS
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Contributions are welcome! Read <a href="https://postgresus.com/contribute">contributing guide</a> for more details, priorities and rules are specified there. If you want to contribute, but don't know what and how - message me on Telegram [@rostislav_dugin](https://t.me/rostislav_dugin)
|
||||
Contributions are welcome! Read the <a href="https://databasus.com/contribute">contributing guide</a> for more details, priorities and rules. If you want to contribute but don't know where to start, message me on Telegram [@rostislav_dugin](https://t.me/rostislav_dugin)
|
||||
|
||||
Also you can join our large community of developers, DBAs and DevOps engineers on Telegram [@databasus_community](https://t.me/databasus_community).
|
||||
|
||||
--
|
||||
|
||||
## 📖 Migration guide
|
||||
|
||||
Databasus is the new name for Postgresus. You can stay with latest version of Postgresus if you wish. If you want to migrate - follow installation steps for Databasus itself.
|
||||
|
||||
Just renaming an image is not enough as Postgresus and Databasus use different data folders and internal database naming.
|
||||
|
||||
You can put a new Databasus image with updated volume near the old Postgresus and run it (stop Postgresus before):
|
||||
|
||||
```
|
||||
services:
|
||||
databasus:
|
||||
container_name: databasus
|
||||
image: databasus/databasus:latest
|
||||
ports:
|
||||
- "4005:4005"
|
||||
volumes:
|
||||
- ./databasus-data:/databasus-data
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
Then manually move databases from Postgresus to Databasus.
|
||||
|
||||
### Why was Postgresus renamed to Databasus?
|
||||
|
||||
Databasus has been developed since 2023. It was internal tool to backup production and home projects databases. In start of 2025 it was released as open source project on GitHub. By the end of 2025 it became popular and the time for renaming has come in December 2025.
|
||||
|
||||
It was an important step for the project to grow. Actually, there are a couple of reasons:
|
||||
|
||||
1. Postgresus is no longer a little tool that just adds UI for pg_dump for little projects. It became a tool both for individual users, DevOps, DBAs, teams, companies and even large enterprises. Tens of thousands of users use Postgresus every day. Postgresus grew into a reliable backup management tool. Initial positioning is no longer suitable: the project is not just a UI wrapper, it's a solid backup management system now (despite it's still easy to use).
|
||||
|
||||
2. New databases are supported: although the primary focus is PostgreSQL (with 100% support in the most efficient way) and always will be, Databasus added support for MySQL, MariaDB and MongoDB. Later more databases will be supported.
|
||||
|
||||
3. Trademark issue: "postgres" is a trademark of PostgreSQL Inc. and cannot be used in the project name. So for safety and legal reasons, we had to rename the project.
|
||||
|
||||
## AI disclaimer
|
||||
|
||||
There have been questions about AI usage in project development in issues and discussions. As the project focuses on security, reliability and production usage, it's important to explain how AI is used in the development process.
|
||||
|
||||
AI is used as a helper for:
|
||||
|
||||
- verification of code quality and searching for vulnerabilities
|
||||
- cleaning up and improving documentation, comments and code
|
||||
- assistance during development
|
||||
- double-checking PRs and commits after human review
|
||||
|
||||
AI is not used for:
|
||||
|
||||
- writing entire code
|
||||
- "vibe code" approach
|
||||
- code without line-by-line verification by a human
|
||||
- code without tests
|
||||
|
||||
The project has:
|
||||
|
||||
- solid test coverage (both unit and integration tests)
|
||||
- CI/CD pipeline automation with tests and linting to ensure code quality
|
||||
- verification by experienced developers with experience in large and secure projects
|
||||
|
||||
So AI is just an assistant and a tool for developers to increase productivity and ensure code quality. The work is done by developers.
|
||||
|
||||
Moreover, it's important to note that we do not differentiate between bad human code and AI vibe code. There are strict requirements for any code to be merged to keep the codebase maintainable.
|
||||
|
||||
Even if code is written manually by a human, it's not guaranteed to be merged. Vibe code is not allowed at all and all such PRs are rejected by default (see [contributing guide](https://databasus.com/contribute)).
|
||||
|
||||
We also draw attention to fast issue resolution and security [vulnerability reporting](https://github.com/databasus/databasus?tab=security-ov-file#readme).
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 766 KiB After Width: | Height: | Size: 766 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 771 KiB After Width: | Height: | Size: 772 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.7 KiB |
BIN
assets/tools/arm/mysql/mysql-9/bin/mysql
Normal file
BIN
assets/tools/arm/mysql/mysql-9/bin/mysql
Normal file
Binary file not shown.
BIN
assets/tools/arm/mysql/mysql-9/bin/mysqldump
Normal file
BIN
assets/tools/arm/mysql/mysql-9/bin/mysqldump
Normal file
Binary file not shown.
BIN
assets/tools/x64/mysql/mysql-9/bin/mysql
Normal file
BIN
assets/tools/x64/mysql/mysql-9/bin/mysql
Normal file
Binary file not shown.
BIN
assets/tools/x64/mysql/mysql-9/bin/mysqldump
Normal file
BIN
assets/tools/x64/mysql/mysql-9/bin/mysqldump
Normal file
Binary file not shown.
@@ -21,7 +21,7 @@ package audit_logs
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
user_models "postgresus/internal/features/users/models"
|
||||
user_models "databasus-backend/internal/features/users/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -12,7 +12,7 @@ package audit_logs
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
user_models "postgresus/internal/features/users/models"
|
||||
user_models "databasus-backend/internal/features/users/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
@@ -132,12 +132,12 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
user_enums "postgresus/internal/features/users/enums"
|
||||
users_middleware "postgresus/internal/features/users/middleware"
|
||||
users_services "postgresus/internal/features/users/services"
|
||||
users_testing "postgresus/internal/features/users/testing"
|
||||
"postgresus/internal/storage"
|
||||
test_utils "postgresus/internal/util/testing"
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
"databasus-backend/internal/storage"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
@@ -268,8 +268,8 @@ func createRouter() *gin.Engine {
|
||||
package audit_logs
|
||||
|
||||
import (
|
||||
users_services "postgresus/internal/features/users/services"
|
||||
"postgresus/internal/util/logger"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var auditLogRepository = &AuditLogRepository{}
|
||||
@@ -350,7 +350,7 @@ func (AuditLog) TableName() string {
|
||||
package audit_logs
|
||||
|
||||
import (
|
||||
"postgresus/internal/storage"
|
||||
"databasus-backend/internal/storage"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -453,8 +453,8 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
user_enums "postgresus/internal/features/users/enums"
|
||||
user_models "postgresus/internal/features/users/models"
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
user_models "databasus-backend/internal/features/users/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -585,8 +585,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
user_enums "postgresus/internal/features/users/enums"
|
||||
users_testing "postgresus/internal/features/users/testing"
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# docker-compose.yml
|
||||
DEV_DB_NAME=postgresus
|
||||
DEV_DB_NAME=databasus
|
||||
DEV_DB_USERNAME=postgres
|
||||
DEV_DB_PASSWORD=Q1234567
|
||||
#app
|
||||
ENV_MODE=development
|
||||
# db
|
||||
DATABASE_DSN=host=dev-db user=postgres password=Q1234567 dbname=postgresus port=5437 sslmode=disable
|
||||
DATABASE_URL=postgres://postgres:Q1234567@dev-db:5437/postgresus?sslmode=disable
|
||||
DATABASE_DSN=host=dev-db user=postgres password=Q1234567 dbname=databasus port=5437 sslmode=disable
|
||||
DATABASE_URL=postgres://postgres:Q1234567@dev-db:5437/databasus?sslmode=disable
|
||||
# migrations
|
||||
GOOSE_DRIVER=postgres
|
||||
GOOSE_DBSTRING=postgres://postgres:Q1234567@dev-db:5437/postgresus?sslmode=disable
|
||||
GOOSE_DBSTRING=postgres://postgres:Q1234567@dev-db:5437/databasus?sslmode=disable
|
||||
GOOSE_MIGRATION_DIR=./migrations
|
||||
# testing
|
||||
# to get Google Drive env variables: add storage in UI and copy data from added storage here
|
||||
@@ -67,4 +67,4 @@ TEST_MONGODB_44_PORT=27044
|
||||
TEST_MONGODB_50_PORT=27050
|
||||
TEST_MONGODB_60_PORT=27060
|
||||
TEST_MONGODB_70_PORT=27070
|
||||
TEST_MONGODB_80_PORT=27080
|
||||
TEST_MONGODB_82_PORT=27082
|
||||
@@ -1,13 +1,13 @@
|
||||
# docker-compose.yml
|
||||
DEV_DB_NAME=postgresus
|
||||
DEV_DB_NAME=databasus
|
||||
DEV_DB_USERNAME=postgres
|
||||
DEV_DB_PASSWORD=Q1234567
|
||||
#app
|
||||
ENV_MODE=production
|
||||
# db
|
||||
DATABASE_DSN=host=localhost user=postgres password=Q1234567 dbname=postgresus port=5437 sslmode=disable
|
||||
DATABASE_URL=postgres://postgres:Q1234567@localhost:5437/postgresus?sslmode=disable
|
||||
DATABASE_DSN=host=localhost user=postgres password=Q1234567 dbname=databasus port=5437 sslmode=disable
|
||||
DATABASE_URL=postgres://postgres:Q1234567@localhost:5437/databasus?sslmode=disable
|
||||
# migrations
|
||||
GOOSE_DRIVER=postgres
|
||||
GOOSE_DBSTRING=postgres://postgres:Q1234567@localhost:5437/postgresus?sslmode=disable
|
||||
GOOSE_DBSTRING=postgres://postgres:Q1234567@localhost:5437/databasus?sslmode=disable
|
||||
GOOSE_MIGRATION_DIR=./migrations
|
||||
1
backend/.gitignore
vendored
1
backend/.gitignore
vendored
@@ -12,6 +12,7 @@ swagger/docs.go
|
||||
swagger/swagger.json
|
||||
swagger/swagger.yaml
|
||||
postgresus-backend.exe
|
||||
databasus-backend.exe
|
||||
ui/build/*
|
||||
pgdata-for-restore/
|
||||
temp/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
# Before run
|
||||
|
||||
Keep in mind: you need to use dev-db from docker-compose.yml in this folder
|
||||
instead of postgresus-db from docker-compose.yml in the root folder.
|
||||
instead of databasus-db from docker-compose.yml in the root folder.
|
||||
|
||||
> Copy .env.example to .env
|
||||
> Copy docker-compose.yml.example to docker-compose.yml (for development only)
|
||||
|
||||
@@ -12,27 +12,27 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
"postgresus-backend/internal/features/audit_logs"
|
||||
"postgresus-backend/internal/features/backups/backups"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/disk"
|
||||
"postgresus-backend/internal/features/encryption/secrets"
|
||||
healthcheck_attempt "postgresus-backend/internal/features/healthcheck/attempt"
|
||||
healthcheck_config "postgresus-backend/internal/features/healthcheck/config"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/restores"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
system_healthcheck "postgresus-backend/internal/features/system/healthcheck"
|
||||
users_controllers "postgresus-backend/internal/features/users/controllers"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
users_services "postgresus-backend/internal/features/users/services"
|
||||
workspaces_controllers "postgresus-backend/internal/features/workspaces/controllers"
|
||||
env_utils "postgresus-backend/internal/util/env"
|
||||
files_utils "postgresus-backend/internal/util/files"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
_ "postgresus-backend/swagger" // swagger docs
|
||||
"databasus-backend/internal/config"
|
||||
"databasus-backend/internal/features/audit_logs"
|
||||
"databasus-backend/internal/features/backups/backups"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/disk"
|
||||
"databasus-backend/internal/features/encryption/secrets"
|
||||
healthcheck_attempt "databasus-backend/internal/features/healthcheck/attempt"
|
||||
healthcheck_config "databasus-backend/internal/features/healthcheck/config"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/restores"
|
||||
"databasus-backend/internal/features/storages"
|
||||
system_healthcheck "databasus-backend/internal/features/system/healthcheck"
|
||||
users_controllers "databasus-backend/internal/features/users/controllers"
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
|
||||
env_utils "databasus-backend/internal/util/env"
|
||||
files_utils "databasus-backend/internal/util/files"
|
||||
"databasus-backend/internal/util/logger"
|
||||
_ "databasus-backend/swagger" // swagger docs
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-contrib/gzip"
|
||||
@@ -41,9 +41,9 @@ import (
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
)
|
||||
|
||||
// @title Postgresus Backend API
|
||||
// @title Databasus Backend API
|
||||
// @version 1.0
|
||||
// @description API for Postgresus
|
||||
// @description API for Databasus
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
|
||||
// @host localhost:4005
|
||||
@@ -238,6 +238,10 @@ func runBackgroundTasks(log *slog.Logger) {
|
||||
go runWithPanicLogging(log, "healthcheck attempt background service", func() {
|
||||
healthcheck_attempt.GetHealthcheckAttemptBackgroundService().Run()
|
||||
})
|
||||
|
||||
go runWithPanicLogging(log, "audit log cleanup background service", func() {
|
||||
audit_logs.GetAuditLogBackgroundService().Run()
|
||||
})
|
||||
}
|
||||
|
||||
func runWithPanicLogging(log *slog.Logger, serviceName string, fn func()) {
|
||||
|
||||
@@ -213,6 +213,25 @@ services:
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
test-mysql-90:
|
||||
image: mysql:9.5
|
||||
ports:
|
||||
- "${TEST_MYSQL_90_PORT:-33090}:3306"
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=rootpassword
|
||||
- MYSQL_DATABASE=testdb
|
||||
- MYSQL_USER=testuser
|
||||
- MYSQL_PASSWORD=testpassword
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
volumes:
|
||||
- ./mysqldata/mysql-90:/var/lib/mysql
|
||||
container_name: test-mysql-90
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpassword"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
# Test MariaDB containers
|
||||
test-mariadb-55:
|
||||
image: mariadb:5.5
|
||||
@@ -520,11 +539,11 @@ services:
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
test-mongodb-80:
|
||||
image: mongo:8.0
|
||||
container_name: test-mongodb-80
|
||||
test-mongodb-82:
|
||||
image: mongo:8.2.3-noble
|
||||
container_name: test-mongodb-82
|
||||
ports:
|
||||
- "${TEST_MONGODB_80_PORT:-27080}:27017"
|
||||
- "${TEST_MONGODB_82_PORT:-27082}:27017"
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: rootpassword
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module postgresus-backend
|
||||
module databasus-backend
|
||||
|
||||
go 1.24.4
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
env_utils "databasus-backend/internal/util/env"
|
||||
"databasus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/util/tools"
|
||||
"os"
|
||||
"path/filepath"
|
||||
env_utils "postgresus-backend/internal/util/env"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -57,6 +57,7 @@ type EnvVariables struct {
|
||||
TestMysql57Port string `env:"TEST_MYSQL_57_PORT"`
|
||||
TestMysql80Port string `env:"TEST_MYSQL_80_PORT"`
|
||||
TestMysql84Port string `env:"TEST_MYSQL_84_PORT"`
|
||||
TestMysql90Port string `env:"TEST_MYSQL_90_PORT"`
|
||||
|
||||
TestMariadb55Port string `env:"TEST_MARIADB_55_PORT"`
|
||||
TestMariadb101Port string `env:"TEST_MARIADB_101_PORT"`
|
||||
@@ -76,7 +77,7 @@ type EnvVariables struct {
|
||||
TestMongodb50Port string `env:"TEST_MONGODB_50_PORT"`
|
||||
TestMongodb60Port string `env:"TEST_MONGODB_60_PORT"`
|
||||
TestMongodb70Port string `env:"TEST_MONGODB_70_PORT"`
|
||||
TestMongodb80Port string `env:"TEST_MONGODB_80_PORT"`
|
||||
TestMongodb82Port string `env:"TEST_MONGODB_82_PORT"`
|
||||
|
||||
// oauth
|
||||
GitHubClientID string `env:"GITHUB_CLIENT_ID"`
|
||||
@@ -189,10 +190,10 @@ func loadEnvVariables() {
|
||||
tools.VerifyMongodbInstallation(log, env.EnvMode, env.MongodbInstallDir)
|
||||
|
||||
// Store the data and temp folders one level below the root
|
||||
// (projectRoot/postgresus-data -> /postgresus-data)
|
||||
env.DataFolder = filepath.Join(filepath.Dir(backendRoot), "postgresus-data", "backups")
|
||||
env.TempFolder = filepath.Join(filepath.Dir(backendRoot), "postgresus-data", "temp")
|
||||
env.SecretKeyPath = filepath.Join(filepath.Dir(backendRoot), "postgresus-data", "secret.key")
|
||||
// (projectRoot/databasus-data -> /databasus-data)
|
||||
env.DataFolder = filepath.Join(filepath.Dir(backendRoot), "databasus-data", "backups")
|
||||
env.TempFolder = filepath.Join(filepath.Dir(backendRoot), "databasus-data", "temp")
|
||||
env.SecretKeyPath = filepath.Join(filepath.Dir(backendRoot), "databasus-data", "secret.key")
|
||||
|
||||
if env.IsTesting {
|
||||
if env.TestPostgres12Port == "" {
|
||||
|
||||
36
backend/internal/features/audit_logs/background_service.go
Normal file
36
backend/internal/features/audit_logs/background_service.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package audit_logs
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/config"
|
||||
"log/slog"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AuditLogBackgroundService struct {
|
||||
auditLogService *AuditLogService
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (s *AuditLogBackgroundService) Run() {
|
||||
s.logger.Info("Starting audit log cleanup background service")
|
||||
|
||||
if config.IsShouldShutdown() {
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
if config.IsShouldShutdown() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.cleanOldAuditLogs(); err != nil {
|
||||
s.logger.Error("Failed to clean old audit logs", "error", err)
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AuditLogBackgroundService) cleanOldAuditLogs() error {
|
||||
return s.auditLogService.CleanOldAuditLogs()
|
||||
}
|
||||
141
backend/internal/features/audit_logs/background_service_test.go
Normal file
141
backend/internal/features/audit_logs/background_service_test.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package audit_logs
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/storage"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Test_CleanOldAuditLogs_DeletesLogsOlderThanOneYear(t *testing.T) {
|
||||
service := GetAuditLogService()
|
||||
user := users_testing.CreateTestUser(user_enums.UserRoleMember)
|
||||
db := storage.GetDb()
|
||||
baseTime := time.Now().UTC()
|
||||
|
||||
// Create old logs (more than 1 year old)
|
||||
createTimedAuditLog(db, &user.UserID, "Old log 1", baseTime.Add(-400*24*time.Hour))
|
||||
createTimedAuditLog(db, &user.UserID, "Old log 2", baseTime.Add(-370*24*time.Hour))
|
||||
|
||||
// Create recent logs (less than 1 year old)
|
||||
createAuditLog(service, "Recent log 1", &user.UserID, nil)
|
||||
createAuditLog(service, "Recent log 2", &user.UserID, nil)
|
||||
|
||||
// Run cleanup
|
||||
err := service.CleanOldAuditLogs()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Verify old logs were deleted
|
||||
oneYearAgo := baseTime.Add(-365 * 24 * time.Hour)
|
||||
var oldLogs []*AuditLog
|
||||
db.Where("created_at < ?", oneYearAgo).Find(&oldLogs)
|
||||
assert.Equal(t, 0, len(oldLogs), "All logs older than 1 year should be deleted")
|
||||
|
||||
// Verify recent logs still exist
|
||||
var recentLogs []*AuditLog
|
||||
db.Where("created_at >= ?", oneYearAgo).Find(&recentLogs)
|
||||
assert.GreaterOrEqual(t, len(recentLogs), 2, "Recent logs should not be deleted")
|
||||
}
|
||||
|
||||
func Test_CleanOldAuditLogs_PreservesLogsNewerThanOneYear(t *testing.T) {
|
||||
service := GetAuditLogService()
|
||||
user := users_testing.CreateTestUser(user_enums.UserRoleMember)
|
||||
db := storage.GetDb()
|
||||
baseTime := time.Now().UTC()
|
||||
|
||||
// Create logs exactly at boundary (1 year old)
|
||||
boundaryTime := baseTime.Add(-365 * 24 * time.Hour)
|
||||
createTimedAuditLog(db, &user.UserID, "Boundary log", boundaryTime)
|
||||
|
||||
// Create recent logs
|
||||
createTimedAuditLog(db, &user.UserID, "Recent log 1", baseTime.Add(-364*24*time.Hour))
|
||||
createTimedAuditLog(db, &user.UserID, "Recent log 2", baseTime.Add(-100*24*time.Hour))
|
||||
createAuditLog(service, "Current log", &user.UserID, nil)
|
||||
|
||||
// Get count before cleanup
|
||||
var countBefore int64
|
||||
db.Model(&AuditLog{}).Count(&countBefore)
|
||||
|
||||
// Run cleanup
|
||||
err := service.CleanOldAuditLogs()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get count after cleanup
|
||||
var countAfter int64
|
||||
db.Model(&AuditLog{}).Count(&countAfter)
|
||||
|
||||
// Verify logs newer than 1 year are preserved
|
||||
oneYearAgo := baseTime.Add(-365 * 24 * time.Hour)
|
||||
var recentLogs []*AuditLog
|
||||
db.Where("created_at >= ?", oneYearAgo).Find(&recentLogs)
|
||||
|
||||
messages := make([]string, len(recentLogs))
|
||||
for i, log := range recentLogs {
|
||||
messages[i] = log.Message
|
||||
}
|
||||
|
||||
assert.Contains(t, messages, "Recent log 1")
|
||||
assert.Contains(t, messages, "Recent log 2")
|
||||
assert.Contains(t, messages, "Current log")
|
||||
}
|
||||
|
||||
func Test_CleanOldAuditLogs_HandlesEmptyDatabase(t *testing.T) {
|
||||
service := GetAuditLogService()
|
||||
|
||||
// Run cleanup on database that may have no old logs
|
||||
err := service.CleanOldAuditLogs()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_CleanOldAuditLogs_DeletesMultipleOldLogs(t *testing.T) {
|
||||
service := GetAuditLogService()
|
||||
user := users_testing.CreateTestUser(user_enums.UserRoleMember)
|
||||
db := storage.GetDb()
|
||||
baseTime := time.Now().UTC()
|
||||
|
||||
// Create many old logs with specific UUIDs to track them
|
||||
testLogIDs := make([]uuid.UUID, 5)
|
||||
for i := 0; i < 5; i++ {
|
||||
testLogIDs[i] = uuid.New()
|
||||
daysAgo := 400 + (i * 10)
|
||||
log := &AuditLog{
|
||||
ID: testLogIDs[i],
|
||||
UserID: &user.UserID,
|
||||
Message: fmt.Sprintf("Test old log %d", i),
|
||||
CreatedAt: baseTime.Add(-time.Duration(daysAgo) * 24 * time.Hour),
|
||||
}
|
||||
result := db.Create(log)
|
||||
assert.NoError(t, result.Error)
|
||||
}
|
||||
|
||||
// Verify logs exist before cleanup
|
||||
var logsBeforeCleanup []*AuditLog
|
||||
db.Where("id IN ?", testLogIDs).Find(&logsBeforeCleanup)
|
||||
assert.Equal(t, 5, len(logsBeforeCleanup), "All test logs should exist before cleanup")
|
||||
|
||||
// Run cleanup
|
||||
err := service.CleanOldAuditLogs()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Verify test logs were deleted
|
||||
var logsAfterCleanup []*AuditLog
|
||||
db.Where("id IN ?", testLogIDs).Find(&logsAfterCleanup)
|
||||
assert.Equal(t, 0, len(logsAfterCleanup), "All old test logs should be deleted")
|
||||
}
|
||||
|
||||
func createTimedAuditLog(db *gorm.DB, userID *uuid.UUID, message string, createdAt time.Time) {
|
||||
log := &AuditLog{
|
||||
ID: uuid.New(),
|
||||
UserID: userID,
|
||||
Message: message,
|
||||
CreatedAt: createdAt,
|
||||
}
|
||||
db.Create(log)
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package audit_logs
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
user_models "postgresus-backend/internal/features/users/models"
|
||||
user_models "databasus-backend/internal/features/users/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
user_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
users_services "postgresus-backend/internal/features/users/services"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
test_utils "postgresus-backend/internal/util/testing"
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
package audit_logs
|
||||
|
||||
import (
|
||||
users_services "postgresus-backend/internal/features/users/services"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var auditLogRepository = &AuditLogRepository{}
|
||||
var auditLogService = &AuditLogService{
|
||||
auditLogRepository: auditLogRepository,
|
||||
logger: logger.GetLogger(),
|
||||
auditLogRepository,
|
||||
logger.GetLogger(),
|
||||
}
|
||||
var auditLogController = &AuditLogController{
|
||||
auditLogService: auditLogService,
|
||||
auditLogService,
|
||||
}
|
||||
var auditLogBackgroundService = &AuditLogBackgroundService{
|
||||
auditLogService,
|
||||
logger.GetLogger(),
|
||||
}
|
||||
|
||||
func GetAuditLogService() *AuditLogService {
|
||||
@@ -22,6 +26,10 @@ func GetAuditLogController() *AuditLogController {
|
||||
return auditLogController
|
||||
}
|
||||
|
||||
func GetAuditLogBackgroundService() *AuditLogBackgroundService {
|
||||
return auditLogBackgroundService
|
||||
}
|
||||
|
||||
func SetupDependencies() {
|
||||
users_services.GetUserService().SetAuditLogWriter(auditLogService)
|
||||
users_services.GetSettingsService().SetAuditLogWriter(auditLogService)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package audit_logs
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/storage"
|
||||
"databasus-backend/internal/storage"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -137,3 +137,15 @@ func (r *AuditLogRepository) CountGlobal(beforeDate *time.Time) (int64, error) {
|
||||
err := query.Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *AuditLogRepository) DeleteOlderThan(beforeDate time.Time) (int64, error) {
|
||||
result := storage.GetDb().
|
||||
Where("created_at < ?", beforeDate).
|
||||
Delete(&AuditLog{})
|
||||
|
||||
if result.Error != nil {
|
||||
return 0, result.Error
|
||||
}
|
||||
|
||||
return result.RowsAffected, nil
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
user_enums "postgresus-backend/internal/features/users/enums"
|
||||
user_models "postgresus-backend/internal/features/users/models"
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
user_models "databasus-backend/internal/features/users/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -135,3 +135,19 @@ func (s *AuditLogService) GetWorkspaceAuditLogs(
|
||||
Offset: offset,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AuditLogService) CleanOldAuditLogs() error {
|
||||
oneYearAgo := time.Now().UTC().Add(-365 * 24 * time.Hour)
|
||||
|
||||
deletedCount, err := s.auditLogRepository.DeleteOlderThan(oneYearAgo)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to delete old audit logs", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if deletedCount > 0 {
|
||||
s.logger.Info("Deleted old audit logs", "count", deletedCount, "olderThan", oneYearAgo)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
user_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
user_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/config"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/period"
|
||||
"log/slog"
|
||||
"postgresus-backend/internal/config"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/period"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/intervals"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
"postgresus-backend/internal/util/period"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/intervals"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
"databasus-backend/internal/util/period"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/databases"
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
@@ -193,8 +193,8 @@ func (c *BackupController) GetFile(ctx *gin.Context) {
|
||||
}
|
||||
}()
|
||||
|
||||
extension := ".dump.zst"
|
||||
if dbType == databases.DatabaseTypeMysql {
|
||||
extension := ".dump"
|
||||
if dbType == databases.DatabaseTypeMysql || dbType == databases.DatabaseTypeMariadb {
|
||||
extension = ".sql.zst"
|
||||
}
|
||||
|
||||
|
||||
@@ -15,21 +15,21 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
audit_logs "postgresus-backend/internal/features/audit_logs"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
local_storage "postgresus-backend/internal/features/storages/models/local"
|
||||
users_dto "postgresus-backend/internal/features/users/dto"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_services "postgresus-backend/internal/features/users/services"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_models "postgresus-backend/internal/features/workspaces/models"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
test_utils "postgresus-backend/internal/util/testing"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
audit_logs "databasus-backend/internal/features/audit_logs"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
"databasus-backend/internal/features/storages"
|
||||
local_storage "databasus-backend/internal/features/storages/models/local"
|
||||
users_dto "databasus-backend/internal/features/users/dto"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_models "databasus-backend/internal/features/workspaces/models"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func Test_GetBackups_PermissionsEnforced(t *testing.T) {
|
||||
@@ -585,6 +585,7 @@ func createTestDatabase(
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@ package backups
|
||||
import (
|
||||
"time"
|
||||
|
||||
audit_logs "postgresus-backend/internal/features/audit_logs"
|
||||
"postgresus-backend/internal/features/backups/backups/usecases"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
audit_logs "databasus-backend/internal/features/audit_logs"
|
||||
"databasus-backend/internal/features/backups/backups/usecases"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var backupRepository = &BackupRepository{}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/backups/backups/encryption"
|
||||
"io"
|
||||
"postgresus-backend/internal/features/backups/backups/encryption"
|
||||
)
|
||||
|
||||
type GetBackupsRequest struct {
|
||||
|
||||
@@ -3,11 +3,11 @@ package backups
|
||||
import (
|
||||
"context"
|
||||
|
||||
usecases_common "postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
usecases_common "databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/storage"
|
||||
"errors"
|
||||
"postgresus-backend/internal/storage"
|
||||
|
||||
"time"
|
||||
|
||||
|
||||
@@ -11,16 +11,16 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
audit_logs "postgresus-backend/internal/features/audit_logs"
|
||||
"postgresus-backend/internal/features/backups/backups/encryption"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
users_models "postgresus-backend/internal/features/users/models"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
util_encryption "postgresus-backend/internal/util/encryption"
|
||||
audit_logs "databasus-backend/internal/features/audit_logs"
|
||||
"databasus-backend/internal/features/backups/backups/encryption"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
users_models "databasus-backend/internal/features/users/models"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
util_encryption "databasus-backend/internal/util/encryption"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
@@ -7,18 +7,18 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package backups
|
||||
|
||||
import (
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
workspaces_controllers "postgresus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package common
|
||||
|
||||
import backups_config "postgresus-backend/internal/features/backups/config"
|
||||
import backups_config "databasus-backend/internal/features/backups/config"
|
||||
|
||||
type BackupMetadata struct {
|
||||
EncryptionSalt *string
|
||||
|
||||
@@ -4,14 +4,14 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
usecases_common "postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
usecases_mariadb "postgresus-backend/internal/features/backups/backups/usecases/mariadb"
|
||||
usecases_mongodb "postgresus-backend/internal/features/backups/backups/usecases/mongodb"
|
||||
usecases_mysql "postgresus-backend/internal/features/backups/backups/usecases/mysql"
|
||||
usecases_postgresql "postgresus-backend/internal/features/backups/backups/usecases/postgresql"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
usecases_common "databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
usecases_mariadb "databasus-backend/internal/features/backups/backups/usecases/mariadb"
|
||||
usecases_mongodb "databasus-backend/internal/features/backups/backups/usecases/mongodb"
|
||||
usecases_mysql "databasus-backend/internal/features/backups/backups/usecases/mysql"
|
||||
usecases_postgresql "databasus-backend/internal/features/backups/backups/usecases/postgresql"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/storages"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package usecases
|
||||
|
||||
import (
|
||||
usecases_mariadb "postgresus-backend/internal/features/backups/backups/usecases/mariadb"
|
||||
usecases_mongodb "postgresus-backend/internal/features/backups/backups/usecases/mongodb"
|
||||
usecases_mysql "postgresus-backend/internal/features/backups/backups/usecases/mysql"
|
||||
usecases_postgresql "postgresus-backend/internal/features/backups/backups/usecases/postgresql"
|
||||
usecases_mariadb "databasus-backend/internal/features/backups/backups/usecases/mariadb"
|
||||
usecases_mongodb "databasus-backend/internal/features/backups/backups/usecases/mongodb"
|
||||
usecases_mysql "databasus-backend/internal/features/backups/backups/usecases/mysql"
|
||||
usecases_postgresql "databasus-backend/internal/features/backups/backups/usecases/postgresql"
|
||||
)
|
||||
|
||||
var createBackupUsecase = &CreateBackupUsecase{
|
||||
|
||||
@@ -17,16 +17,16 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
backup_encryption "postgresus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
mariadbtypes "postgresus-backend/internal/features/databases/databases/mariadb"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
backup_encryption "databasus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
mariadbtypes "databasus-backend/internal/features/databases/databases/mariadb"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package usecases_mariadb
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var createMariadbBackupUsecase = &CreateMariadbBackupUsecase{
|
||||
|
||||
@@ -14,16 +14,16 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
backup_encryption "postgresus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
mongodbtypes "postgresus-backend/internal/features/databases/databases/mongodb"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
backup_encryption "databasus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
mongodbtypes "databasus-backend/internal/features/databases/databases/mongodb"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -106,6 +106,13 @@ func (uc *CreateMongodbBackupUsecase) buildMongodumpArgs(
|
||||
"--gzip",
|
||||
}
|
||||
|
||||
// Use numParallelCollections based on CPU count
|
||||
// Cap between 1 and 16 to balance performance and resource usage
|
||||
parallelCollections := max(1, min(mdb.CpuCount, 16))
|
||||
if parallelCollections > 1 {
|
||||
args = append(args, "--numParallelCollections="+fmt.Sprintf("%d", parallelCollections))
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package usecases_mongodb
|
||||
|
||||
import (
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var createMongodbBackupUsecase = &CreateMongodbBackupUsecase{
|
||||
|
||||
@@ -17,16 +17,16 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
backup_encryption "postgresus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
mysqltypes "postgresus-backend/internal/features/databases/databases/mysql"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
backup_encryption "databasus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
mysqltypes "databasus-backend/internal/features/databases/databases/mysql"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -133,7 +133,7 @@ func (uc *CreateMysqlBackupUsecase) getNetworkCompressionArgs(version tools.Mysq
|
||||
const zstdCompressionLevel = 5
|
||||
|
||||
switch version {
|
||||
case tools.MysqlVersion80, tools.MysqlVersion84:
|
||||
case tools.MysqlVersion80, tools.MysqlVersion84, tools.MysqlVersion9:
|
||||
return []string{
|
||||
"--compression-algorithms=zstd",
|
||||
fmt.Sprintf("--zstd-compression-level=%d", zstdCompressionLevel),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package usecases_mysql
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var createMysqlBackupUsecase = &CreateMysqlBackupUsecase{
|
||||
|
||||
@@ -14,16 +14,16 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
backup_encryption "postgresus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "postgresus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "postgresus-backend/internal/features/backups/config"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
pgtypes "postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
encryption_secrets "postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
backup_encryption "databasus-backend/internal/features/backups/backups/encryption"
|
||||
usecases_common "databasus-backend/internal/features/backups/backups/usecases/common"
|
||||
backups_config "databasus-backend/internal/features/backups/config"
|
||||
"databasus-backend/internal/features/databases"
|
||||
pgtypes "databasus-backend/internal/features/databases/databases/postgresql"
|
||||
encryption_secrets "databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -139,7 +139,7 @@ func (uc *CreatePostgresqlBackupUsecase) streamToStorage(
|
||||
cmd := exec.CommandContext(ctx, pgBin, args...)
|
||||
uc.logger.Info("Executing PostgreSQL backup command", "command", cmd.String())
|
||||
|
||||
if err := uc.setupPgEnvironment(cmd, pgpassFile, db.Postgresql.IsHttps, password, backupConfig.CpuCount, pgBin); err != nil {
|
||||
if err := uc.setupPgEnvironment(cmd, pgpassFile, db.Postgresql.IsHttps, password, db.Postgresql.CpuCount, pgBin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -335,6 +335,11 @@ func (uc *CreatePostgresqlBackupUsecase) buildPgDumpArgs(pg *pgtypes.PostgresqlD
|
||||
"--verbose",
|
||||
}
|
||||
|
||||
// Add parallel jobs based on CPU count
|
||||
if pg.CpuCount > 1 {
|
||||
args = append(args, "-j", strconv.Itoa(pg.CpuCount))
|
||||
}
|
||||
|
||||
for _, schema := range pg.IncludeSchemas {
|
||||
args = append(args, "-n", schema)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package usecases_postgresql
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/encryption/secrets"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/features/encryption/secrets"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var createPostgresqlBackupUsecase = &CreatePostgresqlBackupUsecase{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package backups_config
|
||||
|
||||
import (
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
"net/http"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -9,17 +9,17 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
"postgresus-backend/internal/features/intervals"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "postgresus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
"postgresus-backend/internal/util/period"
|
||||
test_utils "postgresus-backend/internal/util/testing"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
"databasus-backend/internal/features/intervals"
|
||||
"databasus-backend/internal/features/storages"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
"databasus-backend/internal/util/period"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func createTestRouter() *gin.Engine {
|
||||
@@ -109,7 +109,6 @@ func Test_SaveBackupConfig_PermissionsEnforced(t *testing.T) {
|
||||
SendNotificationsOn: []BackupNotificationType{
|
||||
NotificationBackupFailed,
|
||||
},
|
||||
CpuCount: 2,
|
||||
IsRetryIfFailed: true,
|
||||
MaxFailedTriesCount: 3,
|
||||
}
|
||||
@@ -129,7 +128,6 @@ func Test_SaveBackupConfig_PermissionsEnforced(t *testing.T) {
|
||||
assert.Equal(t, database.ID, response.DatabaseID)
|
||||
assert.True(t, response.IsBackupsEnabled)
|
||||
assert.Equal(t, period.PeriodWeek, response.StorePeriod)
|
||||
assert.Equal(t, 2, response.CpuCount)
|
||||
} else {
|
||||
assert.Contains(t, string(testResp.Body), "insufficient permissions")
|
||||
}
|
||||
@@ -158,7 +156,6 @@ func Test_SaveBackupConfig_WhenUserIsNotWorkspaceMember_ReturnsForbidden(t *test
|
||||
SendNotificationsOn: []BackupNotificationType{
|
||||
NotificationBackupFailed,
|
||||
},
|
||||
CpuCount: 2,
|
||||
IsRetryIfFailed: true,
|
||||
MaxFailedTriesCount: 3,
|
||||
}
|
||||
@@ -290,7 +287,6 @@ func Test_GetBackupConfigByDbID_ReturnsDefaultConfigForNewDatabase(t *testing.T)
|
||||
assert.Equal(t, database.ID, response.DatabaseID)
|
||||
assert.False(t, response.IsBackupsEnabled)
|
||||
assert.Equal(t, period.PeriodWeek, response.StorePeriod)
|
||||
assert.Equal(t, 1, response.CpuCount)
|
||||
assert.True(t, response.IsRetryIfFailed)
|
||||
assert.Equal(t, 3, response.MaxFailedTriesCount)
|
||||
assert.NotNil(t, response.BackupInterval)
|
||||
@@ -387,7 +383,6 @@ func Test_SaveBackupConfig_WithEncryptionNone_ConfigSaved(t *testing.T) {
|
||||
SendNotificationsOn: []BackupNotificationType{
|
||||
NotificationBackupFailed,
|
||||
},
|
||||
CpuCount: 2,
|
||||
IsRetryIfFailed: true,
|
||||
MaxFailedTriesCount: 3,
|
||||
Encryption: BackupEncryptionNone,
|
||||
@@ -427,7 +422,6 @@ func Test_SaveBackupConfig_WithEncryptionEncrypted_ConfigSaved(t *testing.T) {
|
||||
SendNotificationsOn: []BackupNotificationType{
|
||||
NotificationBackupFailed,
|
||||
},
|
||||
CpuCount: 2,
|
||||
IsRetryIfFailed: true,
|
||||
MaxFailedTriesCount: 3,
|
||||
Encryption: BackupEncryptionEncrypted,
|
||||
@@ -466,6 +460,7 @@ func createTestDatabaseViaAPI(
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package backups_config
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/storages"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
)
|
||||
|
||||
var backupConfigRepository = &BackupConfigRepository{}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package backups_config
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/intervals"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/period"
|
||||
"errors"
|
||||
"postgresus-backend/internal/features/intervals"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/period"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -30,8 +30,6 @@ type BackupConfig struct {
|
||||
IsRetryIfFailed bool `json:"isRetryIfFailed" gorm:"column:is_retry_if_failed;type:boolean;not null"`
|
||||
MaxFailedTriesCount int `json:"maxFailedTriesCount" gorm:"column:max_failed_tries_count;type:int;not null"`
|
||||
|
||||
CpuCount int `json:"cpuCount" gorm:"type:int;not null"`
|
||||
|
||||
Encryption BackupEncryption `json:"encryption" gorm:"column:encryption;type:text;not null;default:'NONE'"`
|
||||
}
|
||||
|
||||
@@ -82,10 +80,6 @@ func (b *BackupConfig) Validate() error {
|
||||
return errors.New("store period is required")
|
||||
}
|
||||
|
||||
if b.CpuCount == 0 {
|
||||
return errors.New("cpu count is required")
|
||||
}
|
||||
|
||||
if b.IsRetryIfFailed && b.MaxFailedTriesCount <= 0 {
|
||||
return errors.New("max failed tries count must be greater than 0")
|
||||
}
|
||||
@@ -109,7 +103,6 @@ func (b *BackupConfig) Copy(newDatabaseID uuid.UUID) *BackupConfig {
|
||||
SendNotificationsOn: b.SendNotificationsOn,
|
||||
IsRetryIfFailed: b.IsRetryIfFailed,
|
||||
MaxFailedTriesCount: b.MaxFailedTriesCount,
|
||||
CpuCount: b.CpuCount,
|
||||
Encryption: b.Encryption,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package backups_config
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/storage"
|
||||
"errors"
|
||||
"postgresus-backend/internal/storage"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -3,12 +3,12 @@ package backups_config
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/intervals"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
users_models "postgresus-backend/internal/features/users/models"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"postgresus-backend/internal/util/period"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/intervals"
|
||||
"databasus-backend/internal/features/storages"
|
||||
users_models "databasus-backend/internal/features/users/models"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/util/period"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -168,7 +168,6 @@ func (s *BackupConfigService) initializeDefaultConfig(
|
||||
NotificationBackupFailed,
|
||||
NotificationBackupSuccess,
|
||||
},
|
||||
CpuCount: 1,
|
||||
IsRetryIfFailed: true,
|
||||
MaxFailedTriesCount: 3,
|
||||
Encryption: BackupEncryptionNone,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package backups_config
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/intervals"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/period"
|
||||
"databasus-backend/internal/features/intervals"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/period"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -28,7 +28,6 @@ func EnableBackupsForTestDatabase(
|
||||
NotificationBackupFailed,
|
||||
NotificationBackupSuccess,
|
||||
},
|
||||
CpuCount: 1,
|
||||
}
|
||||
|
||||
backupConfig, err := GetBackupConfigService().SaveBackupConfig(backupConfig)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package databases
|
||||
|
||||
import (
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"net/http"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
users_services "postgresus-backend/internal/features/users/services"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -11,16 +11,16 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/features/databases/databases/mariadb"
|
||||
"postgresus-backend/internal/features/databases/databases/mongodb"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "postgresus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
test_utils "postgresus-backend/internal/util/testing"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/features/databases/databases/mariadb"
|
||||
"databasus-backend/internal/features/databases/databases/mongodb"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func createTestRouter() *gin.Engine {
|
||||
@@ -100,6 +100,7 @@ func Test_CreateDatabase_PermissionsEnforced(t *testing.T) {
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -143,6 +144,7 @@ func Test_CreateDatabase_WhenUserIsNotWorkspaceMember_ReturnsForbidden(t *testin
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -747,6 +749,7 @@ func createTestDatabaseViaAPI(
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -790,6 +793,7 @@ func Test_CreateDatabase_PasswordIsEncryptedInDB(t *testing.T) {
|
||||
Username: "postgres",
|
||||
Password: plainPassword,
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -862,6 +866,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) {
|
||||
Username: "postgres",
|
||||
Password: "original-password-secret",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -879,6 +884,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) {
|
||||
Username: "updated_user",
|
||||
Password: "",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -953,7 +959,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) {
|
||||
Name: "Test MongoDB Database",
|
||||
Type: DatabaseTypeMongodb,
|
||||
Mongodb: &mongodb.MongodbDatabase{
|
||||
Version: tools.MongodbVersion70,
|
||||
Version: tools.MongodbVersion7,
|
||||
Host: "localhost",
|
||||
Port: 27017,
|
||||
Username: "root",
|
||||
@@ -961,6 +967,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) {
|
||||
Database: "test_db",
|
||||
AuthDatabase: "admin",
|
||||
IsHttps: false,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -971,7 +978,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) {
|
||||
Name: "Updated MongoDB Database",
|
||||
Type: DatabaseTypeMongodb,
|
||||
Mongodb: &mongodb.MongodbDatabase{
|
||||
Version: tools.MongodbVersion80,
|
||||
Version: tools.MongodbVersion8,
|
||||
Host: "updated-host",
|
||||
Port: 27018,
|
||||
Username: "updated_user",
|
||||
@@ -979,6 +986,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) {
|
||||
Database: "updated_test_db",
|
||||
AuthDatabase: "admin",
|
||||
IsHttps: false,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func Test_IsUserReadOnly_AdminUser_ReturnsFalse(t *testing.T) {
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@@ -30,6 +30,7 @@ type MongodbDatabase struct {
|
||||
Database string `json:"database" gorm:"type:text;not null"`
|
||||
AuthDatabase string `json:"authDatabase" gorm:"type:text;not null;default:'admin'"`
|
||||
IsHttps bool `json:"isHttps" gorm:"type:boolean;default:false"`
|
||||
CpuCount int `json:"cpuCount" gorm:"column:cpu_count;type:int;not null;default:1"`
|
||||
}
|
||||
|
||||
func (m *MongodbDatabase) TableName() string {
|
||||
@@ -52,6 +53,9 @@ func (m *MongodbDatabase) Validate() error {
|
||||
if m.Database == "" {
|
||||
return errors.New("database is required")
|
||||
}
|
||||
if m.CpuCount <= 0 {
|
||||
return errors.New("cpu count must be greater than 0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,6 +113,7 @@ func (m *MongodbDatabase) Update(incoming *MongodbDatabase) {
|
||||
m.Database = incoming.Database
|
||||
m.AuthDatabase = incoming.AuthDatabase
|
||||
m.IsHttps = incoming.IsHttps
|
||||
m.CpuCount = incoming.CpuCount
|
||||
|
||||
if incoming.Password != "" {
|
||||
m.Password = incoming.Password
|
||||
@@ -284,7 +289,7 @@ func (m *MongodbDatabase) CreateReadOnlyUser(
|
||||
|
||||
maxRetries := 3
|
||||
for attempt := range maxRetries {
|
||||
newUsername := fmt.Sprintf("postgresus-%s", uuid.New().String()[:8])
|
||||
newUsername := fmt.Sprintf("databasus-%s", uuid.New().String()[:8])
|
||||
newPassword := uuid.New().String()
|
||||
|
||||
adminDB := client.Database(authDB)
|
||||
@@ -381,35 +386,29 @@ func detectMongodbVersion(ctx context.Context, client *mongo.Client) (tools.Mong
|
||||
return "", errors.New("could not parse MongoDB version from buildInfo")
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`^(\d+)\.(\d+)`)
|
||||
re := regexp.MustCompile(`^(\d+)\.`)
|
||||
matches := re.FindStringSubmatch(versionStr)
|
||||
if len(matches) < 3 {
|
||||
if len(matches) < 2 {
|
||||
return "", fmt.Errorf("could not parse MongoDB version: %s", versionStr)
|
||||
}
|
||||
|
||||
major := matches[1]
|
||||
minor := matches[2]
|
||||
versionKey := fmt.Sprintf("%s.%s", major, minor)
|
||||
|
||||
switch versionKey {
|
||||
case "4.0":
|
||||
return tools.MongodbVersion40, nil
|
||||
case "4.2":
|
||||
return tools.MongodbVersion42, nil
|
||||
case "4.4":
|
||||
return tools.MongodbVersion44, nil
|
||||
case "5.0":
|
||||
return tools.MongodbVersion50, nil
|
||||
case "6.0":
|
||||
return tools.MongodbVersion60, nil
|
||||
case "7.0":
|
||||
return tools.MongodbVersion70, nil
|
||||
case "8.0":
|
||||
return tools.MongodbVersion80, nil
|
||||
switch major {
|
||||
case "4":
|
||||
return tools.MongodbVersion4, nil
|
||||
case "5":
|
||||
return tools.MongodbVersion5, nil
|
||||
case "6":
|
||||
return tools.MongodbVersion6, nil
|
||||
case "7":
|
||||
return tools.MongodbVersion7, nil
|
||||
case "8":
|
||||
return tools.MongodbVersion8, nil
|
||||
default:
|
||||
return "", fmt.Errorf(
|
||||
"unsupported MongoDB version: %s (supported: 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, 8.0)",
|
||||
versionKey,
|
||||
"unsupported MongoDB major version: %s (supported: 4.x, 5.x, 6.x, 7.x, 8.x)",
|
||||
major,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func Test_IsUserReadOnly_AdminUser_ReturnsFalse(t *testing.T) {
|
||||
@@ -26,13 +26,13 @@ func Test_IsUserReadOnly_AdminUser_ReturnsFalse(t *testing.T) {
|
||||
version tools.MongodbVersion
|
||||
port string
|
||||
}{
|
||||
{"MongoDB 4.0", tools.MongodbVersion40, env.TestMongodb40Port},
|
||||
{"MongoDB 4.2", tools.MongodbVersion42, env.TestMongodb42Port},
|
||||
{"MongoDB 4.4", tools.MongodbVersion44, env.TestMongodb44Port},
|
||||
{"MongoDB 5.0", tools.MongodbVersion50, env.TestMongodb50Port},
|
||||
{"MongoDB 6.0", tools.MongodbVersion60, env.TestMongodb60Port},
|
||||
{"MongoDB 7.0", tools.MongodbVersion70, env.TestMongodb70Port},
|
||||
{"MongoDB 8.0", tools.MongodbVersion80, env.TestMongodb80Port},
|
||||
{"MongoDB 4.0", tools.MongodbVersion4, env.TestMongodb40Port},
|
||||
{"MongoDB 4.2", tools.MongodbVersion4, env.TestMongodb42Port},
|
||||
{"MongoDB 4.4", tools.MongodbVersion4, env.TestMongodb44Port},
|
||||
{"MongoDB 5.0", tools.MongodbVersion5, env.TestMongodb50Port},
|
||||
{"MongoDB 6.0", tools.MongodbVersion6, env.TestMongodb60Port},
|
||||
{"MongoDB 7.0", tools.MongodbVersion7, env.TestMongodb70Port},
|
||||
{"MongoDB 8.2", tools.MongodbVersion8, env.TestMongodb82Port},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -60,13 +60,13 @@ func Test_CreateReadOnlyUser_UserCanReadButNotWrite(t *testing.T) {
|
||||
version tools.MongodbVersion
|
||||
port string
|
||||
}{
|
||||
{"MongoDB 4.0", tools.MongodbVersion40, env.TestMongodb40Port},
|
||||
{"MongoDB 4.2", tools.MongodbVersion42, env.TestMongodb42Port},
|
||||
{"MongoDB 4.4", tools.MongodbVersion44, env.TestMongodb44Port},
|
||||
{"MongoDB 5.0", tools.MongodbVersion50, env.TestMongodb50Port},
|
||||
{"MongoDB 6.0", tools.MongodbVersion60, env.TestMongodb60Port},
|
||||
{"MongoDB 7.0", tools.MongodbVersion70, env.TestMongodb70Port},
|
||||
{"MongoDB 8.0", tools.MongodbVersion80, env.TestMongodb80Port},
|
||||
{"MongoDB 4.0", tools.MongodbVersion4, env.TestMongodb40Port},
|
||||
{"MongoDB 4.2", tools.MongodbVersion4, env.TestMongodb42Port},
|
||||
{"MongoDB 4.4", tools.MongodbVersion4, env.TestMongodb44Port},
|
||||
{"MongoDB 5.0", tools.MongodbVersion5, env.TestMongodb50Port},
|
||||
{"MongoDB 6.0", tools.MongodbVersion6, env.TestMongodb60Port},
|
||||
{"MongoDB 7.0", tools.MongodbVersion7, env.TestMongodb70Port},
|
||||
{"MongoDB 8.2", tools.MongodbVersion8, env.TestMongodb82Port},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -95,7 +95,7 @@ func Test_CreateReadOnlyUser_UserCanReadButNotWrite(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, username)
|
||||
assert.NotEmpty(t, password)
|
||||
assert.True(t, strings.HasPrefix(username, "postgresus-"))
|
||||
assert.True(t, strings.HasPrefix(username, "databasus-"))
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
@@ -139,7 +139,7 @@ func Test_CreateReadOnlyUser_UserCanReadButNotWrite(t *testing.T) {
|
||||
|
||||
func Test_ReadOnlyUser_FutureCollections_CanSelect(t *testing.T) {
|
||||
env := config.GetEnv()
|
||||
container := connectToMongodbContainer(t, env.TestMongodb70Port, tools.MongodbVersion70)
|
||||
container := connectToMongodbContainer(t, env.TestMongodb70Port, tools.MongodbVersion7)
|
||||
defer container.Client.Disconnect(context.Background())
|
||||
|
||||
ctx := context.Background()
|
||||
@@ -170,7 +170,7 @@ func Test_ReadOnlyUser_FutureCollections_CanSelect(t *testing.T) {
|
||||
|
||||
func Test_ReadOnlyUser_CannotDropOrModifyCollections(t *testing.T) {
|
||||
env := config.GetEnv()
|
||||
container := connectToMongodbContainer(t, env.TestMongodb70Port, tools.MongodbVersion70)
|
||||
container := connectToMongodbContainer(t, env.TestMongodb70Port, tools.MongodbVersion7)
|
||||
defer container.Client.Disconnect(context.Background())
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/google/uuid"
|
||||
@@ -258,7 +258,7 @@ func (m *MysqlDatabase) CreateReadOnlyUser(
|
||||
|
||||
maxRetries := 3
|
||||
for attempt := range maxRetries {
|
||||
newUsername := fmt.Sprintf("postgresus-%s", uuid.New().String()[:8])
|
||||
newUsername := fmt.Sprintf("databasus-%s", uuid.New().String()[:8])
|
||||
newPassword := uuid.New().String()
|
||||
|
||||
tx, err := db.BeginTx(ctx, nil)
|
||||
@@ -370,7 +370,7 @@ func mapMysqlVersion(major, minor string) (tools.MysqlVersion, error) {
|
||||
case "8":
|
||||
return mapMysql8xVersion(minor), nil
|
||||
case "9":
|
||||
return tools.MysqlVersion84, nil
|
||||
return tools.MysqlVersion9, nil
|
||||
default:
|
||||
return "", fmt.Errorf(
|
||||
"unsupported MySQL major version: %s (supported: 5.x, 8.x, 9.x)",
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func Test_IsUserReadOnly_AdminUser_ReturnsFalse(t *testing.T) {
|
||||
@@ -28,6 +28,7 @@ func Test_IsUserReadOnly_AdminUser_ReturnsFalse(t *testing.T) {
|
||||
{"MySQL 5.7", tools.MysqlVersion57, env.TestMysql57Port},
|
||||
{"MySQL 8.0", tools.MysqlVersion80, env.TestMysql80Port},
|
||||
{"MySQL 8.4", tools.MysqlVersion84, env.TestMysql84Port},
|
||||
{"MySQL 9", tools.MysqlVersion9, env.TestMysql90Port},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -58,6 +59,7 @@ func Test_CreateReadOnlyUser_UserCanReadButNotWrite(t *testing.T) {
|
||||
{"MySQL 5.7", tools.MysqlVersion57, env.TestMysql57Port},
|
||||
{"MySQL 8.0", tools.MysqlVersion80, env.TestMysql80Port},
|
||||
{"MySQL 8.4", tools.MysqlVersion84, env.TestMysql84Port},
|
||||
{"MySQL 9", tools.MysqlVersion9, env.TestMysql90Port},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -95,7 +97,7 @@ func Test_CreateReadOnlyUser_UserCanReadButNotWrite(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, username)
|
||||
assert.NotEmpty(t, password)
|
||||
assert.True(t, strings.HasPrefix(username, "postgresus-"))
|
||||
assert.True(t, strings.HasPrefix(username, "databasus-"))
|
||||
|
||||
readOnlyModel := &MysqlDatabase{
|
||||
Version: mysqlModel.Version,
|
||||
@@ -240,7 +242,7 @@ func Test_CreateReadOnlyUser_DatabaseNameWithDash_Success(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, username)
|
||||
assert.NotEmpty(t, password)
|
||||
assert.True(t, strings.HasPrefix(username, "postgresus-"))
|
||||
assert.True(t, strings.HasPrefix(username, "databasus-"))
|
||||
|
||||
readOnlyDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true",
|
||||
username, password, container.Host, container.Port, dashDbName)
|
||||
|
||||
@@ -2,11 +2,11 @@ package postgresql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/tools"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -34,6 +34,7 @@ type PostgresqlDatabase struct {
|
||||
// backup settings
|
||||
IncludeSchemas []string `json:"includeSchemas" gorm:"-"`
|
||||
IncludeSchemasString string `json:"-" gorm:"column:include_schemas;type:text;not null;default:''"`
|
||||
CpuCount int `json:"cpuCount" gorm:"column:cpu_count;type:int;not null;default:1"`
|
||||
|
||||
// restore settings (not saved to DB)
|
||||
IsExcludeExtensions bool `json:"isExcludeExtensions" gorm:"-"`
|
||||
@@ -80,6 +81,10 @@ func (p *PostgresqlDatabase) Validate() error {
|
||||
return errors.New("password is required")
|
||||
}
|
||||
|
||||
if p.CpuCount <= 0 {
|
||||
return errors.New("cpu count must be greater than 0")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -110,6 +115,7 @@ func (p *PostgresqlDatabase) Update(incoming *PostgresqlDatabase) {
|
||||
p.Database = incoming.Database
|
||||
p.IsHttps = incoming.IsHttps
|
||||
p.IncludeSchemas = incoming.IncludeSchemas
|
||||
p.CpuCount = incoming.CpuCount
|
||||
|
||||
if incoming.Password != "" {
|
||||
p.Password = incoming.Password
|
||||
@@ -319,7 +325,7 @@ func (p *PostgresqlDatabase) IsUserReadOnly(
|
||||
// 5. Sets default privileges for future tables and sequences
|
||||
//
|
||||
// Security features:
|
||||
// - Username format: "postgresus-{8-char-uuid}" for uniqueness
|
||||
// - Username format: "databasus-{8-char-uuid}" for uniqueness
|
||||
// - Password: Full UUID (36 characters) for strong entropy
|
||||
// - Transaction safety: All operations rollback on any failure
|
||||
// - Retry logic: Up to 3 attempts if username collision occurs
|
||||
@@ -365,7 +371,7 @@ func (p *PostgresqlDatabase) CreateReadOnlyUser(
|
||||
maxRetries := 3
|
||||
for attempt := range maxRetries {
|
||||
// Generate base username for PostgreSQL user creation
|
||||
baseUsername := fmt.Sprintf("postgresus-%s", uuid.New().String()[:8])
|
||||
baseUsername := fmt.Sprintf("databasus-%s", uuid.New().String()[:8])
|
||||
|
||||
// For Supabase session pooler, the username format for connection is "username.projectid"
|
||||
// but the actual PostgreSQL user must be created with just the base name.
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/config"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func Test_IsUserReadOnly_AdminUser_ReturnsFalse(t *testing.T) {
|
||||
@@ -93,7 +93,7 @@ func Test_CreateReadOnlyUser_UserCanReadButNotWrite(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, username)
|
||||
assert.NotEmpty(t, password)
|
||||
assert.True(t, strings.HasPrefix(username, "postgresus-"))
|
||||
assert.True(t, strings.HasPrefix(username, "databasus-"))
|
||||
|
||||
readOnlyModel := &PostgresqlDatabase{
|
||||
Version: pgModel.Version,
|
||||
@@ -295,7 +295,7 @@ func Test_CreateReadOnlyUser_DatabaseNameWithDash_Success(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, username)
|
||||
assert.NotEmpty(t, password)
|
||||
assert.True(t, strings.HasPrefix(username, "postgresus-"))
|
||||
assert.True(t, strings.HasPrefix(username, "databasus-"))
|
||||
|
||||
readOnlyDSN := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
|
||||
container.Host, container.Port, username, password, dashDbName)
|
||||
@@ -378,7 +378,7 @@ func Test_CreateReadOnlyUser_Supabase_UserCanReadButNotWrite(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, connectionUsername)
|
||||
assert.NotEmpty(t, newPassword)
|
||||
assert.True(t, strings.HasPrefix(connectionUsername, "postgresus-"))
|
||||
assert.True(t, strings.HasPrefix(connectionUsername, "databasus-"))
|
||||
|
||||
baseUsername := connectionUsername
|
||||
if idx := strings.Index(connectionUsername, "."); idx != -1 {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package databases
|
||||
|
||||
import (
|
||||
audit_logs "postgresus-backend/internal/features/audit_logs"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
users_services "postgresus-backend/internal/features/users/services"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
audit_logs "databasus-backend/internal/features/audit_logs"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
users_services "databasus-backend/internal/features/users/services"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var databaseRepository = &DatabaseRepository{}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package databases
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"log/slog"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package databases
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/databases/databases/mariadb"
|
||||
"databasus-backend/internal/features/databases/databases/mongodb"
|
||||
"databasus-backend/internal/features/databases/databases/mysql"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"postgresus-backend/internal/features/databases/databases/mariadb"
|
||||
"postgresus-backend/internal/features/databases/databases/mongodb"
|
||||
"postgresus-backend/internal/features/databases/databases/mysql"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package databases
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/databases/databases/mariadb"
|
||||
"databasus-backend/internal/features/databases/databases/mongodb"
|
||||
"databasus-backend/internal/features/databases/databases/mysql"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
"databasus-backend/internal/storage"
|
||||
"errors"
|
||||
"postgresus-backend/internal/features/databases/databases/mariadb"
|
||||
"postgresus-backend/internal/features/databases/databases/mongodb"
|
||||
"postgresus-backend/internal/features/databases/databases/mysql"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
"postgresus-backend/internal/storage"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -7,15 +7,15 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
audit_logs "postgresus-backend/internal/features/audit_logs"
|
||||
"postgresus-backend/internal/features/databases/databases/mariadb"
|
||||
"postgresus-backend/internal/features/databases/databases/mongodb"
|
||||
"postgresus-backend/internal/features/databases/databases/mysql"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
users_models "postgresus-backend/internal/features/users/models"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"postgresus-backend/internal/util/encryption"
|
||||
audit_logs "databasus-backend/internal/features/audit_logs"
|
||||
"databasus-backend/internal/features/databases/databases/mariadb"
|
||||
"databasus-backend/internal/features/databases/databases/mongodb"
|
||||
"databasus-backend/internal/features/databases/databases/mysql"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
users_models "databasus-backend/internal/features/users/models"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/util/encryption"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -396,15 +396,17 @@ func (s *DatabaseService) CopyDatabase(
|
||||
case DatabaseTypePostgres:
|
||||
if existingDatabase.Postgresql != nil {
|
||||
newDatabase.Postgresql = &postgresql.PostgresqlDatabase{
|
||||
ID: uuid.Nil,
|
||||
DatabaseID: nil,
|
||||
Version: existingDatabase.Postgresql.Version,
|
||||
Host: existingDatabase.Postgresql.Host,
|
||||
Port: existingDatabase.Postgresql.Port,
|
||||
Username: existingDatabase.Postgresql.Username,
|
||||
Password: existingDatabase.Postgresql.Password,
|
||||
Database: existingDatabase.Postgresql.Database,
|
||||
IsHttps: existingDatabase.Postgresql.IsHttps,
|
||||
ID: uuid.Nil,
|
||||
DatabaseID: nil,
|
||||
Version: existingDatabase.Postgresql.Version,
|
||||
Host: existingDatabase.Postgresql.Host,
|
||||
Port: existingDatabase.Postgresql.Port,
|
||||
Username: existingDatabase.Postgresql.Username,
|
||||
Password: existingDatabase.Postgresql.Password,
|
||||
Database: existingDatabase.Postgresql.Database,
|
||||
IsHttps: existingDatabase.Postgresql.IsHttps,
|
||||
IncludeSchemas: existingDatabase.Postgresql.IncludeSchemas,
|
||||
CpuCount: existingDatabase.Postgresql.CpuCount,
|
||||
}
|
||||
}
|
||||
case DatabaseTypeMysql:
|
||||
@@ -448,6 +450,7 @@ func (s *DatabaseService) CopyDatabase(
|
||||
Database: existingDatabase.Mongodb.Database,
|
||||
AuthDatabase: existingDatabase.Mongodb.AuthDatabase,
|
||||
IsHttps: existingDatabase.Mongodb.IsHttps,
|
||||
CpuCount: existingDatabase.Mongodb.CpuCount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package databases
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
"databasus-backend/internal/util/tools"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -25,6 +25,7 @@ func CreateTestDatabase(
|
||||
Port: 5432,
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
CpuCount: 1,
|
||||
},
|
||||
|
||||
Notifiers: []notifiers.Notifier{
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"postgresus-backend/internal/config"
|
||||
user_models "postgresus-backend/internal/features/users/models"
|
||||
"postgresus-backend/internal/storage"
|
||||
"databasus-backend/internal/config"
|
||||
user_models "databasus-backend/internal/features/users/models"
|
||||
"databasus-backend/internal/storage"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/config"
|
||||
healthcheck_config "databasus-backend/internal/features/healthcheck/config"
|
||||
"log/slog"
|
||||
"postgresus-backend/internal/config"
|
||||
healthcheck_config "postgresus-backend/internal/features/healthcheck/config"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/databases"
|
||||
healthcheck_config "databasus-backend/internal/features/healthcheck/config"
|
||||
"databasus-backend/internal/util/logger"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
healthcheck_config "postgresus-backend/internal/features/healthcheck/config"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"postgresus-backend/internal/features/databases"
|
||||
healthcheck_config "postgresus-backend/internal/features/healthcheck/config"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"postgresus-backend/internal/features/storages"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
"databasus-backend/internal/features/databases"
|
||||
healthcheck_config "databasus-backend/internal/features/healthcheck/config"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/storages"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
"net/http"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
@@ -11,14 +11,14 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "postgresus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
test_utils "postgresus-backend/internal/util/testing"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func createTestRouter() *gin.Engine {
|
||||
@@ -217,6 +217,7 @@ func createTestDatabaseViaAPI(
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/databases"
|
||||
healthcheck_config "postgresus-backend/internal/features/healthcheck/config"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/features/databases"
|
||||
healthcheck_config "databasus-backend/internal/features/healthcheck/config"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var healthcheckAttemptRepository = &HealthcheckAttemptRepository{}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/notifiers"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/notifiers"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/storage"
|
||||
"databasus-backend/internal/storage"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package healthcheck_attempt
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/features/databases"
|
||||
users_models "databasus-backend/internal/features/users/models"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"errors"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
users_models "postgresus-backend/internal/features/users/models"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package healthcheck_config
|
||||
|
||||
import (
|
||||
users_middleware "databasus-backend/internal/features/users/middleware"
|
||||
"net/http"
|
||||
users_middleware "postgresus-backend/internal/features/users/middleware"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -9,14 +9,14 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"postgresus-backend/internal/features/databases"
|
||||
"postgresus-backend/internal/features/databases/databases/postgresql"
|
||||
users_enums "postgresus-backend/internal/features/users/enums"
|
||||
users_testing "postgresus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "postgresus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "postgresus-backend/internal/features/workspaces/testing"
|
||||
test_utils "postgresus-backend/internal/util/testing"
|
||||
"postgresus-backend/internal/util/tools"
|
||||
"databasus-backend/internal/features/databases"
|
||||
"databasus-backend/internal/features/databases/databases/postgresql"
|
||||
users_enums "databasus-backend/internal/features/users/enums"
|
||||
users_testing "databasus-backend/internal/features/users/testing"
|
||||
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
|
||||
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
|
||||
test_utils "databasus-backend/internal/util/testing"
|
||||
"databasus-backend/internal/util/tools"
|
||||
)
|
||||
|
||||
func createTestRouter() *gin.Engine {
|
||||
@@ -305,6 +305,7 @@ func createTestDatabaseViaAPI(
|
||||
Username: "postgres",
|
||||
Password: "postgres",
|
||||
Database: &testDbName,
|
||||
CpuCount: 1,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package healthcheck_config
|
||||
|
||||
import (
|
||||
"postgresus-backend/internal/features/audit_logs"
|
||||
"postgresus-backend/internal/features/databases"
|
||||
workspaces_services "postgresus-backend/internal/features/workspaces/services"
|
||||
"postgresus-backend/internal/util/logger"
|
||||
"databasus-backend/internal/features/audit_logs"
|
||||
"databasus-backend/internal/features/databases"
|
||||
workspaces_services "databasus-backend/internal/features/workspaces/services"
|
||||
"databasus-backend/internal/util/logger"
|
||||
)
|
||||
|
||||
var healthcheckConfigRepository = &HealthcheckConfigRepository{}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package healthcheck_config
|
||||
|
||||
import (
|
||||
"databasus-backend/internal/storage"
|
||||
"errors"
|
||||
"postgresus-backend/internal/storage"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user