Skip to content

Commit

Permalink
chore: create appsmith schema for postgres (#36591)
Browse files Browse the repository at this point in the history
## Description

The current state is default schema or public schema. This schema is
accessible by default when user connects to the pg database. Hence
create `appsmith` schema for Appsmith server to use. This is to avoid
anyone accidentally modifying the appsmith data.

## Automation

/ok-to-test tags="@tag.Sanity"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!IMPORTANT]
> 🟣 🟣 🟣 Your tests are running.
> Tests running at:
<https://github.com/appsmithorg/appsmith/actions/runs/11111681323>
> Commit: 32f91e8
> Workflow: `PR Automation test suite`
> Tags: `@tag.Sanity`
> Spec: ``
> <hr>Mon, 30 Sep 2024 18:08:23 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Introduced a script to initialize the PostgreSQL database schema for
Appsmith.
- Added utilities for managing PostgreSQL database connections,
including availability checks and parameter extraction.
- Enhanced scripts for managing PostgreSQL connections and
initialization.
- Improved environment configuration for PostgreSQL database
connections, including automatic password generation for local setups.
- Updated JDBC URL handling to include schema parameters for PostgreSQL
connections.
	- Added support for proxy configuration in the application setup.

- **Bug Fixes**
- Improved error handling and connection retry mechanisms for PostgreSQL
setup.

- **Documentation**
- Updated comments and logging for better clarity on database
operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Abhijeet <[email protected]>
  • Loading branch information
AnaghHegde and abhvsn committed Sep 30, 2024
1 parent 8145ed2 commit 69ba8b5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,23 @@ public DataSourceProperties extractJdbcProperties(String dbUrl) {
ds.setUsername(userDetails[0]);
ds.setPassword(userDetails[1]);
}
// If the port is not mentioned default it to standard 5432
// If the port is not mentioned, default it to the standard PostgreSQL port 5432
int port = uri.getPort() == -1 ? 5432 : uri.getPort();
String updatedUrl =
String.format("%s%s://%s:%s%s", JDBC_PREFIX, uri.getScheme(), uri.getHost(), port, uri.getPath());

// Check if the URL already has query parameters
String query = uri.getQuery();
String updatedUrl;
if (StringUtils.hasLength(query)) {
// Append currentSchema=appsmith if there are already parameters
updatedUrl = String.format(
"%s%s://%s:%s%s?%s&currentSchema=appsmith",
JDBC_PREFIX, uri.getScheme(), uri.getHost(), port, uri.getPath(), query);
} else {
// No parameters, just append currentSchema
updatedUrl = String.format(
"%s%s://%s:%s%s?currentSchema=appsmith",
JDBC_PREFIX, uri.getScheme(), uri.getHost(), port, uri.getPath());
}
ds.setUrl(updatedUrl);
return ds;
} catch (URISyntaxException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public void testExtractAndSaveJdbcParams_validDbUrlWithUsernameAndPassword() {
DataSourceProperties ds = commonDBConfig.extractJdbcProperties(dbUrl);
assertEquals("postgres", ds.getUsername());
assertEquals("password", ds.getPassword());
assertEquals("jdbc:postgresql://localhost:5432/postgres", ds.getUrl());
assertEquals("jdbc:postgresql://localhost:5432/postgres?currentSchema=appsmith", ds.getUrl());

String dbUrlWithPort = "postgresql://postgres:password@localhost:1234/postgres";
ds = commonDBConfig.extractJdbcProperties(dbUrlWithPort);
assertEquals("postgres", ds.getUsername());
assertEquals("password", ds.getPassword());
assertEquals("jdbc:postgresql://localhost:1234/postgres", ds.getUrl());
assertEquals("jdbc:postgresql://localhost:1234/postgres?currentSchema=appsmith", ds.getUrl());
}

@Test
Expand All @@ -32,7 +32,7 @@ public void testExtractAndSaveJdbcParams_validDbUrlWithoutUsernameAndPassword()
DataSourceProperties ds = commonDBConfig.extractJdbcProperties(dbUrl);
assertNull(ds.getUsername());
assertNull(ds.getPassword());
assertEquals("jdbc:postgresql://localhost:5432/postgres", ds.getUrl());
assertEquals("jdbc:postgresql://localhost:5432/postgres?currentSchema=appsmith", ds.getUrl());
}

@Test
Expand All @@ -44,4 +44,31 @@ public void testExtractAndSaveJdbcParams_invalidDbUrl() {
dbUrl);
assertThrows(IllegalArgumentException.class, () -> commonDBConfig.extractJdbcProperties(dbUrl), errorString);
}

@Test
void testExtractJdbcPropertiesWithQueryParams() {
CommonDBConfig commonDBConfig = new CommonDBConfig();
String dbUrl = "postgresql://user:password@localhost:5432/mydb?sslmode=require";

DataSourceProperties dataSourceProperties = commonDBConfig.extractJdbcProperties(dbUrl);

String expectedUrl = "jdbc:postgresql://localhost:5432/mydb?sslmode=require&currentSchema=appsmith";
assertEquals(
expectedUrl,
dataSourceProperties.getUrl(),
"URL with existing query params should append the currentSchema correctly.");
}

@Test
void testExtractJdbcPropertiesWithoutQueryParams() {
CommonDBConfig commonDBConfig = new CommonDBConfig();
String dbUrl = "postgresql://user:password@localhost:5432/mydb";
DataSourceProperties dataSourceProperties = commonDBConfig.extractJdbcProperties(dbUrl);

String expectedUrl = "jdbc:postgresql://localhost:5432/mydb?currentSchema=appsmith";
assertEquals(
expectedUrl,
dataSourceProperties.getUrl(),
"URL without query params should append the currentSchema correctly.");
}
}
3 changes: 2 additions & 1 deletion deploy/docker/fs/opt/appsmith/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ init_env_file() {
# Generate new docker.env file when initializing container for first time or in Heroku which does not have persistent volume
tlog "Generating default configuration file"
mkdir -p "$CONF_PATH"

local default_appsmith_mongodb_user="appsmith"
local generated_appsmith_mongodb_password=$(
tr -dc A-Za-z0-9 </dev/urandom | head -c 13
Expand All @@ -75,10 +76,10 @@ init_env_file() {
tr -dc A-Za-z0-9 </dev/urandom | head -c 13
echo ''
)

bash "$TEMPLATES_PATH/docker.env.sh" "$default_appsmith_mongodb_user" "$generated_appsmith_mongodb_password" "$generated_appsmith_encryption_password" "$generated_appsmith_encription_salt" "$generated_appsmith_supervisor_password" > "$ENV_PATH"
fi


tlog "Load environment configuration"

# Load the ones in `docker.env` in the stacks folder.
Expand Down
50 changes: 49 additions & 1 deletion deploy/docker/fs/opt/appsmith/pg-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,54 @@ extract_postgres_db_params() {
export PG_DB_NAME="$DB"
}
init_pg_db() {
# Create the appsmith schema
echo "Initializing PostgreSQL with schema..."
# Check if APPSMITH_DB_URL is a PostgreSQL URL
if [[ -n "$APPSMITH_DB_URL" && "$APPSMITH_DB_URL" == postgres*://* ]]; then
echo "APPSMITH_DB_URL is a valid PostgreSQL URL."
# Check if the DB_HOST is local (localhost or 127.0.0.1)
if [[ "$PG_DB_HOST" == "localhost" || "$PG_DB_HOST" == "127.0.0.1" ]]; then
# Check if the database exists
DB_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "postgres" -tAc "SELECT 1 FROM pg_database WHERE datname='$PG_DB_NAME'")
if [ "$DB_CHECK" != "1" ]; then
echo "Database $PG_DB_NAME does not exist. Creating database..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "postgres" -c "CREATE DATABASE $PG_DB_NAME;"
else
echo "Database $PG_DB_NAME already exists."
fi
# Check if the schema exists
SCHEMA_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name='appsmith'")
# Create schema and user if not exists
if [ "$SCHEMA_CHECK" != "1" ]; then
echo "Creating user '$PG_DB_USER' with password "
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER \"$PG_DB_USER\" WITH PASSWORD '$PG_DB_PASSWORD';"
echo "Schema 'appsmith' does not exist. Creating schema..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE SCHEMA appsmith;"
fi
else
echo "Remote PostgreSQL detected, running as current user."
PGPASSWORD=$PG_DB_PASSWORD psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U "$PG_DB_USER" -d "$PG_DB_NAME" -c "CREATE SCHEMA IF NOT EXISTS appsmith;"
fi
# Check if the schema creation was successful
if [ $? -eq 0 ]; then
echo "Schema 'appsmith' created or already exists."
else
echo "Failed to create schema 'appsmith'."
exit 1
fi
echo "PostgreSQL initialization completed."
fi
}
# Example usage of the functions
# waitForPostgresAvailability
# extract_postgres_db_params "postgresql://user:password@localhost:5432/dbname"
# extract_postgres_db_params "postgresql://user:password@localhost:5432/dbname"
1 change: 1 addition & 0 deletions deploy/docker/fs/opt/appsmith/run-java.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ match-proxy-url() {
if [[ "$mode" == "pg" ]]; then
extract_postgres_db_params "$APPSMITH_DB_URL"
waitForPostgresAvailability
init_pg_db
fi
if match-proxy-url "${HTTP_PROXY-}"; then
Expand Down
7 changes: 4 additions & 3 deletions deploy/docker/fs/opt/appsmith/templates/docker.env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -o nounset
MONGO_USER="$1"
MONGO_PASSWORD="$2"
DB_PASSWORD="$2"
ENCRYPTION_PASSWORD="$3"
ENCRYPTION_SALT="$4"
SUPERVISOR_PASSWORD="$5"
Expand Down Expand Up @@ -63,9 +63,10 @@ APPSMITH_RECAPTCHA_SITE_KEY=
APPSMITH_RECAPTCHA_SECRET_KEY=
APPSMITH_RECAPTCHA_ENABLED=
APPSMITH_DB_URL=mongodb://$MONGO_USER:$MONGO_PASSWORD@localhost:27017/appsmith
APPSMITH_DB_URL=mongodb://$MONGO_USER:$DB_PASSWORD@localhost:27017/appsmith
APPSMITH_POSTGRES_DB_URL=postgresql://appsmith:$DB_PASSWORD@localhost:5432/appsmith
APPSMITH_MONGODB_USER=$MONGO_USER
APPSMITH_MONGODB_PASSWORD=$MONGO_PASSWORD
APPSMITH_MONGODB_PASSWORD=$DB_PASSWORD
APPSMITH_API_BASE_URL=http://localhost:8080/api/v1
APPSMITH_REDIS_URL=redis://127.0.0.1:6379
Expand Down

0 comments on commit 69ba8b5

Please sign in to comment.