Simplify development environment setup (#1588)

This commit is contained in:
Oscar Hinton
2021-10-13 19:30:03 +02:00
committed by GitHub
parent 7802c2b969
commit 964e262d44
17 changed files with 429 additions and 149 deletions

3
dev/.env.example Normal file
View File

@@ -0,0 +1,3 @@
COMPOSE_PROJECT_NAME=BitwardenServer
MSSQL_PASSWORD=SET_A_PASSWORD_HERE_123
MAILCATCHER_PORT=1080

10
dev/.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
.data
secrets.json
.env
identity_server_dev.crt
identity_server_dev.key
identity_server_dev.pfx
data_protection_dev.crt
data_protection_dev.key
data_protection_dev.pfx

23
dev/create_certificates_mac.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout identity_server_dev.key -out identity_server_dev.crt \
-subj "/CN=Bitwarden Identity Server Dev" -days 3650
openssl pkcs12 -export -out identity_server_dev.pfx -inkey identity_server_dev.key -in identity_server_dev.crt \
-certfile identity_server_dev.crt
security import ./identity_server_dev.pfx -k ~/Library/Keychains/Login.keychain
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout data_protection_dev.key -out data_protection_dev.crt \
-subj "/CN=Bitwarden Data Protection Dev" -days 3650
openssl pkcs12 -export -out data_protection_dev.pfx -inkey data_protection_dev.key -in data_protection_dev.crt \
-certfile data_protection_dev.crt
security import ./data_protection_dev.pfx -k ~/Library/Keychains/Login.keychain
identity=($(openssl x509 -in identity_server_dev.crt -outform der | shasum -a 1 | tr a-z A-Z));
data=($(openssl x509 -in data_protection_dev.crt -outform der | shasum -a 1 | tr a-z A-Z));
echo "Certificate fingerprints:"
echo "Identity Server Dev: ${identity}"
echo "Data Protection Dev: ${data}"

View File

@@ -0,0 +1,14 @@
# Script for generating and installing the Bitwarden development certificates on Windows.
$params = @{
'KeyAlgorithm' = 'RSA';
'KeyLength' = 4096;
'NotAfter' = (Get-Date).AddDays(3650);
'CertStoreLocation' = 'Cert:\CurrentUser\My';
};
$params['Subject'] = 'CN=Bitwarden Identity Server Dev';
New-SelfSignedCertificate @params;
$params['Subject'] = 'CN=Bitwarden Data Protection Dev';
New-SelfSignedCertificate @params;

43
dev/docker-compose.yml Normal file
View File

@@ -0,0 +1,43 @@
version: "3.9"
services:
mssql:
image: mcr.microsoft.com/mssql/server:2017-latest
restart: always
environment:
ACCEPT_EULA: Y
SA_PASSWORD: ${MSSQL_PASSWORD}
MSSQL_PID: Developer
volumes:
- mssql_dev_data:/var/opt/mssql/data
- ../util/Migrator:/mnt/migrator/
- ./helpers/mssql:/mnt/helpers
- ./.data/mssql:/mnt/data
ports:
- '1433:1433'
profiles:
- cloud
- mssql
storage:
image: mcr.microsoft.com/azure-storage/azurite:latest
ports:
- "10000:10000"
- "10001:10001"
- "10002:10002"
volumes:
- ./.data/azurite:/data
profiles:
- storage
- cloud
mail:
image: sj26/mailcatcher:latest
ports:
- "${MAILCATCHER_PORT}:1080"
- "10250:1025"
profiles:
- mail
volumes:
mssql_dev_data:

View File

@@ -0,0 +1,70 @@
#!/bin/bash
MIGRATE_DIRECTORY="/mnt/migrator/DbScripts"
LAST_MIGRATION_FILE="/mnt/data/last_migration"
SERVER='localhost'
DATABASE="vault_dev"
USER="SA"
PASSWD=$SA_PASSWORD
if [ ! -f "$LAST_MIGRATION_FILE" ]; then
echo "$LAST_MIGRATION_FILE not found!"
echo "This will run all migrations which might cause unexpected behaviour if the database is not empty."
echo
read -p "Run all Migrations? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
LAST_MIGRATION=""
else
LAST_MIGRATION=$(cat $LAST_MIGRATION_FILE)
fi
[ -z "$LAST_MIGRATION" ]
PERFORM_MIGRATION=$?
while getopts "r" arg; do
case $arg in
r)
RERUN=1
;;
esac
done
if [ -n "$RERUN" ]; then
echo "Rerunning the last migration"
fi
# Create database if it does not already exist
QUERY="IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'vault_dev')
BEGIN
CREATE DATABASE vault_dev;
END;"
/opt/mssql-tools/bin/sqlcmd -S $SERVER -d master -U $USER -P $PASSWD -I -Q "$QUERY"
migrate () {
local file=$1
echo "Performing $file"
/opt/mssql-tools/bin/sqlcmd -S $SERVER -d $DATABASE -U $USER -P $PASSWD -I -i $file
echo $file > $LAST_MIGRATION_FILE
}
for f in `ls -v $MIGRATE_DIRECTORY/*.sql`; do
if (( PERFORM_MIGRATION == 0 )); then
migrate $f
else
echo "Skipping $f"
if [ "$LAST_MIGRATION" == "$f" ]; then
PERFORM_MIGRATION=0
# Rerun last migration
if [ -n "$RERUN" ]; then
migrate $f
unset RERUN
fi
fi
fi
done;

4
dev/migrate.ps1 Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env pwsh
# Creates the vault_dev database, and runs all the migrations.
docker-compose --profile mssql exec mssql bash /mnt/helpers/run_migrations.sh @args

22
dev/secrets.json.example Normal file
View File

@@ -0,0 +1,22 @@
{
"adminSettings": {
"admins": "admin@localhost"
},
"globalSettings": {
"selfHosted": true,
"sqlServer": {
"connectionString": "Server=localhost;Database=vault_dev;User Id=SA;Password=SET_A_PASSWORD_HERE_123;"
},
"identityServer": {
"certificateThumbprint": "<your Identity certificate thumbprint with no spaces>"
},
"dataProtection": {
"certificateThumbprint": "<your Data Protection certificate thumbprint with no spaces>"
},
"installation": {
"id": "<your Installation Id>",
"key": "<your Installation Key>"
},
"licenseDirectory": "<full path to licence directory>"
}
}

47
dev/setup_azurite.ps1 Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env pwsh
# Script for configuring the initial state of Azurite Storage account
# Can be run multiple times without negative impact
# Start configuration
$corsRules = (@{
AllowedHeaders = @("*");
ExposedHeaders = @("*");
AllowedOrigins = @("*");
MaxAgeInSeconds = 30;
AllowedMethods = @("Get", "PUT");
});
$containers = "attachments", "sendfiles", "misc";
$queues = "event", "notifications", "reference-events", "mail";
$tables = "event", "metadata", "installationdevice";
# End configuration
$context = New-AzStorageContext -Local
foreach ($container in $containers) {
if (Get-AzStorageContainer -Name $container -Context $context -ErrorAction SilentlyContinue) {
Write-Host -ForegroundColor Magenta "Container already exists:" $container
}
else {
New-AzStorageContainer -Name $container -Context $context
}
}
foreach ($queue in $queues) {
if (Get-AzStorageQueue -Name $queue -Context $context -ErrorAction SilentlyContinue) {
Write-Host -ForegroundColor Magenta "Queue already exists:" $queue
}
else {
New-AzStorageQueue -Name $queue -Context $context
}
}
foreach ($table in $tables) {
if (Get-AzStorageTable -Name $table -Context $context -ErrorAction SilentlyContinue) {
Write-Host -ForegroundColor Magenta "Table already exists:" $table
}
else {
New-AzStorageTable -Name $table -Context $context
}
}
Set-AzStorageCORSRule -ServiceType Blob -CorsRules $corsRules -Context $context

21
dev/setup_secrets.ps1 Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env pwsh
# Helper script for applying the same user secrets to each project
param (
[bool]$clear,
[Parameter(ValueFromRemainingArguments = $true, Position=1)]
$cmdArgs
)
if (!(Test-Path "secrets.json")) {
Write-Warning "No secrets.json file found, please copy and modify the provided example";
exit;
}
$projects = "Admin", "Api", "Billing", "Events", "EventsProcessor", "Icons", "Identity", "Notifications";
foreach ($projects in $projects) {
if ($clear -eq $true) {
dotnet user-secrets clear -p "../src/$projects"
}
Get-Content secrets.json | & dotnet user-secrets set -p "../src/$projects"
}