test/bin/convertdomain
Bernhard Rosenkränzer 30bdb3148a Replace calls to mysql/mysqldump with mariadb/mariadb-dump
The compat symlinks have been removed in current mariadb containers.
Let's not run into nasty surprises when we update.
2025-02-18 13:46:37 +01:00

973 lines
49 KiB
Bash
Executable File

#!/bin/bash -x
#
# Federated Convert Domain
#
# Converts Federated Core services
# From: customer.federatedcomputer.cloud
# To: domain.com
#
# Assumes all services are currently running
. /federated/lib/functions.sh
. /etc/federated
check_gluerecords() {
echo -ne "\n* Checking glue records for $DOMAIN_NEW.."
local DOMAIN_PARENT=$(echo $DOMAIN_NEW |cut -d. -f2-)
local NS_PARENT=""
while true; do
NS_PARENT="$(dig @8.8.8.8 +short NS "$DOMAIN_PARENT." | head -n 1)"
[ -n "$NS_PARENT" ] && break
if ! echo $DOMAIN_PARENT |grep -q '\.'; then
failcheck "Could not determine parent NS for $DOMAIN_NEW"
fi
# When handling a subdomain, the parent NS may not be at the next
# level -- imagine
# DOMAIN_NEW=fed.a.b.c.d.com
# d.com has:
# c NS whatever
# c.d.com has
# b A something
# a.b A something
# fed.a.b NS something
DOMAIN_PARENT="$(echo $DOMAIN_PARENT |cut -d. -f2-)"
done
if dig +noall +authority +additional +norecurse @"$NS_PARENT" NS "$DOMAIN_NEW". | grep NS | grep -iE '\.dns\.fedcom\.net\.'; then
echo "Not needed (using dns.fedcom.net)"
return
fi
CHECK_NS1=`dig +noall +authority +additional +norecurse @"$NS_PARENT" NS "$DOMAIN_NEW". | grep NS | grep -i ns1.$DOMAIN_NEW`
[ $? -ne 0 ] && failcheck "Couldn't find glue / authoritative NS record ns1.$DOMAIN_NEW"
CHECK_NS2=`dig +noall +authority +additional +norecurse @"$NS_PARENT" NS "$DOMAIN_NEW". | grep NS | grep -i ns2.$DOMAIN_NEW`
[ $? -ne 0 ] && failcheck "Couldn't find glue / authoritative NS record ns2.$DOMAIN_NEW"
CHECK_A1=`dig +noall +authority +additional +norecurse @"$NS_PARENT" NS "$DOMAIN_NEW". | grep A | grep -i ns1.$DOMAIN_NEW | grep $EXTERNALIP`
[ $? -ne 0 ] && failcheck "Couldn't find glue / authoritative A record ns1.$DOMAIN_NEW to $EXTERNALIP"
CHECK_A2=`dig +noall +authority +additional +norecurse @"$NS_PARENT" NS "$DOMAIN_NEW". | grep A | grep -i ns2.$DOMAIN_NEW | grep $EXTERNALIP`
[ $? -ne 0 ] && failcheck "Couldn't find glue / authoritative A record ns2.$DOMAIN_NEW to $EXTERNALIP"
echo -ne "done."
}
do_serviceprep_dns() {
# Create DNS records for newdomain
docker exec pdns pdnsutil create-zone $DOMAIN_NEW
docker exec pdns pdnsutil set-kind $DOMAIN_NEW primary
docker exec pdns pdnsutil set-meta $DOMAIN_NEW SOA-EDIT-API DEFAULT
for i in ns1 powerdns traefik mail www computer panel nextcloud collabora jitsi matrix element listmonk vaultwarden vpn wireguard baserow gitea blog documentation podcasts castopod caddy wordpress bookstack freescout msp espocrm dashboard plane calcom; do
docker exec pdns pdnsutil add-record $DOMAIN_NEW $i A 86400 $EXTERNALIP
done
FEDCOMDNS_IP=$(host -t a dns.fedcom.net |cut -d' ' -f4)
docker exec pdns pdnsutil add-record $DOMAIN_NEW ns2 A 86400 $FEDCOMDNS_IP
docker exec pdns pdnsutil add-record $DOMAIN_NEW @ NS ns1.$DOMAIN_NEW
docker exec pdns pdnsutil add-record $DOMAIN_NEW @ NS ns2.$DOMAIN_NEW
docker exec pdns pdnsutil add-record $DOMAIN_NEW @ MX 86400 "10 mail.$DOMAIN_NEW"
docker exec pdns pdnsutil add-record $DOMAIN_NEW @ TXT 86400 "\"v=spf1 mx a:$DOMAIN_NEW ~all\""
docker exec pdns pdnsutil add-record $DOMAIN_NEW \* CNAME 86400 www.$DOMAIN_NEW
docker exec pdns pdnsutil add-record $DOMAIN_NEW @ A 86400 $EXTERNALIP
docker exec pdns pdnsutil activate-tsig-key $DOMAIN_NEW fedcomdns primary
}
do_serviceprep_ldap() {
docker exec ldap bash -c "slapcat > /root/convertdomain.ldif"
# Remove first lines of ldap config, replace dc= with new domain, replace domain name
sed -n '/^dn: ou=people,dc=federatedcomputer,dc=cloud$/,$p' /federated/apps/ldap/data/root/convertdomain.ldif > /federated/apps/ldap/data/root/convertdomain1.ldif
sed -i "s#dc=federatedcomputer,dc=cloud#$DOMAIN_NEW_LDAP_dc#g" /federated/apps/ldap/data/root/convertdomain1.ldif
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/ldap/data/root/convertdomain1.ldif
}
convert_generic() {
#### Conversions that must be done for almost everything
# FIXME check if Jitsi really needs upper-case DC. If we can use lower case dc like everywhere else,
# we can avoid generating DOMAIN_NEW_LDAP_DC
# dc=federatedcomputer,dc=cloud is hardcoded for some stuff in initial
# core creation even if the original domain isn't under federatedcomputer.cloud,
# so let's migrate from that unconditionally
sed -i "s#$DOMAIN#$DOMAIN_NEW#g;s#$DOMAIN_LDAP_dc#$DOMAIN_NEW_LDAP_dc#g;s#$DOMAIN_LDAP_DC#$DOMAIN_NEW_LDAP_DC#g;s#dc=federatedcomputer,dc=cloud#$DOMAIN_NEW_LDAP_dc#g" /federated/apps/$1/docker-compose.yml
[ -e /federated/apps/$1/.env ] && sed -i "s#$DOMAIN#$DOMAIN_NEW#g;s#$DOMAIN_LDAP_dc#$DOMAIN_NEW_LDAP_dc#g;s#$DOMAIN_LDAP_DC#$DOMAIN_NEW_LDAP_DC#g;s#dc=federatedcomputer,dc=cloud#$DOMAIN_NEW_LDAP_dc#g" /federated/apps/$1/.env
}
convert_calcom() {
echo -ne "\n* Converting calcom..."
convert_generic calcom
/federated/bin/sync-calcomusers
start_service_convert "calcom" "nc -z 192.168.0.48 3000 &>/dev/null"
echo done
}
convert_plane() {
echo -ne "\n* Converting plane..."
convert_generic plane
docker exec postgresql psql -U plane -c "UPDATE instances SET domain='$DOMAIN_NEW' WHERE domain='$DOMAIN'"
docker exec postgresql psql -U plane -c "UPDATE users SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'"
docker exec postgresql psql -U plane -c "UPDATE profiles SET company_name='$DOMAIN_NEW' WHERE company_name='$DOMAIN'"
start_service_convert "plane" "nc -z 192.168.0.50 3000 &>/dev/null"
echo done
}
convert_pdnsmysql() {
#### Convert PowerDNS pdnsmysql
echo -ne "\n* Converting pdnsmysql.."
convert_generic pdnsmysql
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/pdnsmysql/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "pdnsmysql" "nc -z ${SERVICE_IP} 3306 &> /dev/null"
echo -ne "done."
}
convert_pdns() {
#### Convert PowerDNS pdns
echo -ne "\n* Converting pdns.."
convert_generic pdns
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/pdns/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "pdns" "nc -z ${SERVICE_IP} 8081 &> /dev/null"
echo -ne "done."
}
convert_pdnsadmin() {
#### Convert PowerDNS pdnsadmin
echo -ne "\n* Converting pdnsadmin.."
convert_generic pdnsadmin
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/pdnsadmin/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "pdnsadmin" "nc -z ${SERVICE_IP} 9494 &> /dev/null"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD pdns -e \"UPDATE user SET username=REPLACE(username, '@$DOMAIN', '@$DOMAIN_NEW') WHERE username LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD pdns -e \"UPDATE user SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN';\""
echo -ne "done."
}
convert_traefik() {
#### Convert Traefik
echo -ne "\n* Converting traefik. "
if ! $DNS_DONE; then
echo -n "Waiting 60s first for dns.."
sleep 60
fi
convert_generic traefik
rm -rf /federated/apps/traefik/data/letsencrypt/acme.json
# Start Traefik
docker compose -f /federated/apps/traefik/docker-compose.yml -p traefik up -d &> /dev/null
# Keep trying to see that certificates are generated
RETRY="20"
while [ $RETRY -gt 0 ]; do
traefik-certs-dumper file --version v2 --source /federated/apps/traefik/data/letsencrypt/acme.json --dest /federated/certs &> /dev/null
# Check if certs are generated
ls /federated/certs/private/$DOMAIN_NEW.key /federated/certs/certs/$DOMAIN_NEW.crt &> /dev/null
if [ $? -eq 0 ]; then
break
else
if [ "$RETRY" == 1 ]; then
docker compose -f /federated/apps/traefik/docker-compose.yml -p traefik down &> /dev/null
failcheck "There was a problem starting service /federated/apps/traefik\nCheck the output of 'docker logs traefik'"
fi
((RETRY--))
sleep 9
fi
done
echo -ne "done."
}
convert_postgresql() {
#### Convert Postgresql
echo -ne "\n* Converting postgresql.."
convert_generic postgresql
cp /federated/certs/certs/$DOMAIN_NEW.crt /federated/apps/postgresql/data/var/lib/postgresql/server.crt
cp /federated/certs/private/$DOMAIN_NEW.key /federated/apps/postgresql/data/var/lib/postgresql/server.key
chown 999 /federated/apps/postgresql/data/var/lib/postgresql/server.crt /federated/apps/postgresql/data/var/lib/postgresql/server.key
chmod 600 /federated/apps/postgresql/data/var/lib/postgresql/server.crt /federated/apps/postgresql/data/var/lib/postgresql/server.key
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/postgresql/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "postgresql" "nc -z ${SERVICE_IP} 5432 &> /dev/null"
echo -ne "done."
}
convert_ldap() {
#### Convert LDAP
echo -ne "\n* Converting ldap.."
# Remove LDAP files so we can start clean
rm -rf /federated/apps/ldap/data/var/lib/ldap/*
rm -rf /federated/apps/ldap/data/etc/ldap/slapd.d/*
rm -rf /federated/apps/ldap/data/root/.ldaprc
rm -rf /federated/apps/ldap/data/certs/dhparam.pem
convert_generic ldap
sed -i "s#LDAP_DOMAIN=.*#LDAP_DOMAIN=$DOMAIN_NEW#g" /federated/apps/ldap/.env
sed -i "s#LDAP_ORGANISATION=.*#LDAP_ORGANISATION=$ORG_NEW#g" /federated/apps/ldap/.env
cp /federated/certs/certs/$DOMAIN_NEW.crt /federated/certs/private/$DOMAIN_NEW.key /federated/apps/ldap/data/certs/
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/ldap/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "ldap" "nc -z $SERVICE_IP 636 &> /dev/null"
# DEBUG output of the ldif
echo "/root/convertdomain1.ldif before import"
echo "---------------------------------------"
cat /federated/apps/ldap/data/root/convertdomain1.ldif
# This imports the modified LDAP configuration above
docker exec ldap bash -c "slapadd -v -l /root/convertdomain1.ldif"
[ $? -ne 0 ] && failcheck "Couldn't slapadd convertdomain1.ldif inside ldap container"
echo -ne "done."
}
convert_mail() {
#### Convert Mail
echo -ne "\n* Converting mail.."
convert_generic mail
cp /federated/certs/certs/$DOMAIN_NEW.crt /federated/certs/private/$DOMAIN_NEW.key /federated/apps/mail/data/root/certs/
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/mail/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "mail" "nc -z $SERVICE_IP 25 &> /dev/null"
# Generate the DKIM DNS key for new domain
docker exec mail setup config dkim keysize 2048 domain $DOMAIN_NEW &> /dev/null
[ $? -ne 0 ] && fail "Couldn't generate DKIM record"
# Insert the DKIM DNS TXT entry into /federated/apps/pdns container
DKIM_RECORD_STRIP=`cat /federated/apps/mail/data/tmp/docker-mailserver/opendkim/keys/$DOMAIN_NEW/mail.txt | sed 's/.*(//'`
DKIM_RECORD=`echo $DKIM_RECORD_STRIP | sed 's/).*//'`
docker exec pdns pdnsutil add-record $DOMAIN_NEW mail._domainkey TXT 86400 "$DKIM_RECORD" &> /dev/null
[ $? -ne 0 ] && fail "Couldn't insert DKIM record into /federated/apps/pdns container"
# Insert the DMARC DNS TXT entry into /federated/apps/pdns container
docker exec pdns pdnsutil add-record $DOMAIN_NEW _dmarc TXT 86400 "\"v=DMARC1; p=quarantine; rua=mailto:admin@$DOMAIN_NEW; ruf=mailto:admin@$DOMAIN_NEW; sp=none; ri=86400\"" &> /dev/null
[ $? -ne 0 ] && fail "Couldn't insert DMARC record into /federated/apps/pdns container"
# Stop and Start mail to reload DKIM
/federated/bin/stop mail &> /dev/null
/federated/bin/start mail &> /dev/null
echo -ne "done."
}
convert_collabora() {
#### Convert Collabora
echo -ne "\n* Converting collabora.."
convert_generic collabora
cp /federated/certs/certs/$DOMAIN_NEW.crt /federated/certs/private/$DOMAIN_NEW.key /federated/apps/collabora/data/root/certs/
chown 104 /federated/apps/collabora/data/root/certs/*
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/collabora/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "collabora" "nc -z $SERVICE_IP 9980 &> /dev/null"
echo -ne "done."
}
convert_nextcloud() {
#### Convert Nextcloud
echo -ne "\n* Converting nextcloud.."
convert_generic nextcloud
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/nextcloud/data/var/www/html/config/config.php
docker exec postgresql psql -U nextcloud -c "UPDATE oc_accounts SET data=REPLACE(data, '$DOMAIN', '$DOMAIN_NEW') WHERE data LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_accounts_data SET value=REPLACE(value, '$DOMAIN', '$DOMAIN_NEW') WHERE value LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_appconfig SET configvalue=REPLACE(configvalue, '$DOMAIN', '$DOMAIN_NEW') WHERE configvalue LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_appconfig SET configvalue=REPLACE(configvalue, '$DOMAIN_LDAP_dc', '$DOMAIN_NEW_LDAP_dc') WHERE configvalue LIKE '%$DOMAIN%'"
# (for initial hardcoded federatedcomputer,cloud in temp domains)
docker exec postgresql psql -U nextcloud -c "UPDATE oc_appconfig SET configvalue=REPLACE(configvalue, 'dc=federatedcomputer,dc=cloud', '$DOMAIN_NEW_LDAP_dc') WHERE configvalue LIKE '%dc=federatedcomputer,dc=cloud'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_mail_accounts SET inbound_host=REPLACE(inbound_host, '$DOMAIN', '$DOMAIN_NEW') WHERE inbound_host LIKE '%$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_preferences SET configvalue=REPLACE(configvalue, '$DOMAIN', '$DOMAIN_NEW') WHERE configvalue LIKE '%$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_richdocuments_wopi SET server_host=REPLACE(server_host, '$DOMAIN', '$DOMAIN_NEW') WHERE server_host LIKE '%$DOMAIN%'"
# Authelia integration...
# FIXME should we just wipe oc_user_oidc_sessions, given they will probably be invalid
# with reconfigured authelia anyway?
docker exec postgresql psql -U nextcloud -c "UPDATE oc_user_oidc_providers SET discovery_endpoint=REPLACE(discovery_endpoint, '$DOMAIN', '$DOMAIN_NEW') WHERE discovery_endpoint LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_user_oidc_providers SET end_session_endpoint=REPLACE(end_session_endpoint, '$DOMAIN', '$DOMAIN_NEW') WHERE end_session_endpoint LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_user_oidc_sessions SET iss=REPLACE(iss, '$DOMAIN', '$DOMAIN_NEW') WHERE iss LIKE '%$DOMAIN%'"
# DAV links...
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendars SET uri=REPLACE(uri, '/$DOMAIN/', '/$DOMAIN_NEW/') WHERE uri LIKE '%/$DOMAIN/%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendars SET displayname=REPLACE(displayname, '/$DOMAIN/', '/$DOMAIN_NEW/') WHERE displayname LIKE '%/$DOMAIN/%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendarsubscriptions SET uri=REPLACE(uri, '$DOMAIN', '$DOMAIN_NEW') WHERE uri LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendarsubscriptions SET displayname=REPLACE(displayname, '/$DOMAIN/', '/$DOMAIN_NEW/') WHERE displayname LIKE '%/$DOMAIN/%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendarsubscriptions SET source=REPLACE(source, '/$DOMAIN/', '/$DOMAIN_NEW/') WHERE source LIKE '%/$DOMAIN/%'"
# Email addresses (for authentication and otherwise)...
docker exec postgresql psql -U nextcloud -c "UPDATE oc_authtoken SET login_name=REPLACE(login_name, '@$DOMAIN', '@$DOMAIN_NEW') WHERE login_name LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendar_invitations SET attendee=REPLACE(attendee, '@$DOMAIN', '@$DOMAIN_NEW') WHERE attendee LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendar_invitations SET organizer=REPLACE(organizer, '@$DOMAIN', '@$DOMAIN_NEW') WHERE attendee LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_cards_properties SET value=REPLACE(value, '@$DOMAIN', '@$DOMAIN_NEW') WHERE value LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_mail_accounts SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_mail_accounts SET inbound_user=REPLACE(inbound_user, '@$DOMAIN', '@$DOMAIN_NEW') WHERE inbound_user LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_mail_coll_addresses SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_mail_recipients SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_mail_trusted_senders SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_recent_contact SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'"
# May contain links to dashboard.$DOMAIN etc.
docker exec postgresql psql -U nextcloud -c "UPDATE oc_bookmarks SET url=REPLACE(url, '$DOMAIN', '$DOMAIN_NEW') WHERE url LIKE '%$DOMAIN%'"
# This can contain Jitsi links
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendar_appt_configs SET location=REPLACE(location, '$DOMAIN', '$DOMAIN_NEW') WHERE location LIKE '%$DOMAIN%'"
docker exec postgresql psql -U nextcloud -c "UPDATE oc_calendarobjects_props SET value=REPLACE(value, '$DOMAIN', '$DOMAIN_NEW') WHERE value LIKE '%$DOMAIN%'"
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/nextcloud/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "nextcloud" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_matrix() {
#### Convert Matrix
echo -ne "\n* Converting matrix.."
# Delete matrix database so we can start from scratch
MATRIX_SECRET=$(create_password);
COTURN_MATRIX_SECRET=$(create_password);
docker exec postgresql psql -U postgres -c "drop database matrix" &> /dev/null
docker exec postgresql psql -U postgres -c "drop user matrix" &> /dev/null
docker exec postgresql psql -U postgres -c "CREATE USER matrix WITH PASSWORD '$MATRIX_SECRET'"
docker exec postgresql psql -U postgres -c "CREATE DATABASE matrix"
docker exec postgresql psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE matrix TO matrix"
convert_generic matrix
rm -rf /federated/apps/matrix/data
mkdir -p /federated/apps/matrix/data/matrix
cp /federated/certs/certs/$DOMAIN_NEW.crt /federated/certs/private/$DOMAIN_NEW.key /federated/apps/matrix/data/matrix/
chmod 644 /federated/apps/matrix/data/matrix/$DOMAIN_NEW.crt /federated/apps/matrix/data/matrix/$DOMAIN_NEW.key
chown -R 991:991 /federated/apps/matrix/data/matrix
# Generate the matrix homeserver.yaml file
docker run --rm -v "/federated/apps/matrix/data/matrix:/data" -e SYNAPSE_SERVER_NAME=matrix.$DOMAIN_NEW -e SYNAPSE_REPORT_STATS=yes matrixdotorg/synapse:latest generate &> /dev/null
[ $? -ne 0 ] && fail "Couldn't run docker matrixdotorg/synapse:latest generate"
# Take out default Sqlite database config
sed -i 's!database: /data/homeserver.db!!g' /federated/apps/matrix/data/matrix/homeserver.yaml
sed -i 's!database:!!g' /federated/apps/matrix/data/matrix/homeserver.yaml
sed -i 's!name: sqlite3!!g' /federated/apps/matrix/data/matrix/homeserver.yaml
sed -i 's!args:!!g' /federated/apps/matrix/data/matrix/homeserver.yaml
# Insert our Postgres and LDAP config
cat >> /federated/apps/matrix/data/matrix/homeserver.yaml <<EOF
web_client_location: https://element.$DOMAIN/
public_baseurl: https://matrix.$DOMAIN_NEW/
serve_server_wellknown: true
turn_uris: [ "turn:turn.$DOMAIN_NEW?transport=udp", "turn:turn.$DOMAIN_NEW?transport=tcp" ]
turn_shared_secret: "$COTURN_MATRIX_SECRET"
turn_user_lifetime: 86400000
database:
name: psycopg2
args:
user: matrix
password: $MATRIX_SECRET
host: postgresql.$DOMAIN_NEW
database: matrix
cp_min: 5
cp_max: 10
email:
smtp_host: "mail.$DOMAIN_NEW"
smtp_port: 587
smtp_user: "$SMTPUSER"
smtp_pass: "$ADMINPASS"
force_tls: true
# require_transport_security: true
enable_tls: true
notif_from: "Your Friendly %(app)s homeserver <matrix@matrix.$DOMAIN_NEW>"
app_name: $ORG_NEW Matrix Server
modules:
- module: "ldap_auth_provider.LdapAuthProviderModule"
config:
enabled: true
uri: "ldaps://ldap.$DOMAIN_NEW:636"
start_tls: true
base: "$DOMAIN_NEW_LDAP_dc"
attributes:
mail: "mail"
uid: "uid"
name: "givenName"
bind_dn: cn=admin,$DOMAIN_NEW_LDAP_dc
bind_password: $LDAP_SECRET
tls_options:
validate: true
local_certificate_file: /data/$DOMAIN_NEW.crt
local_private_key_file: /data/$DOMAIN_NEW.key
EOF
chown -R 991:991 /federated/apps/matrix/data/matrix
# sed -i "s#server_name: \"matrix.$DOMAIN\"#server_name: \"matrix.$DOMAIN_NEW\"#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#smtp_host: \"mail.$DOMAIN\"#smtp_host: \"mail.$DOMAIN_NEW\"#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#notif_from:.*#notif_from: \"Your Friendly %(app)s homeserver <matrix@matrix.$DOMAIN_NEW>\"#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#app_name:.*#app_name: $ORG_NEW Matrix Server#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#postgresql.$DOMAIN#postgresql.$DOMAIN_NEW#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#ldap.$DOMAIN#ldap.$DOMAIN_NEW#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#$DOMAIN.crt#$DOMAIN_NEW.crt#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# sed -i "s#$DOMAIN.key#$DOMAIN_NEW.key#g" /federated/apps/matrix/data/matrix/homeserver.yaml
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/matrix/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "matrix" "nc -z $SERVICE_IP 8008 &> /dev/null"
chown -R 991:991 /federated/apps/matrix/data/matrix
# Set admin user as admin in Matrix
docker exec postgresql psql -U matrix -c "update users set admin='1' where name='\"@admin:matrix.$DOMAIN_NEW\"'" &> /dev/null
# Configure SSO to Authelia
MATRIX_CLIENT_SECRET=$(cat /federated/apps/matrix/.matrix.client.secret)
cat >> /federated/apps/matrix/data/matrix/homeserver.yaml <<EOF
oidc_providers:
- idp_id: authelia
idp_name: "Authelia"
idp_icon: "mxc://authelia.com/cKlrTPsGvlpKxAYeHWJsdVHI"
discover: true
issuer: "https://authelia.$DOMAIN_NEW"
client_id: "matrix"
client_secret: "$MATRIX_CLIENT_SECRET"
scopes: ["openid", "profile", "email"]
allow_existing_users: true
user_mapping_provider:
config:
subject_claim: "sub"
localpart_template: "{{ user.name }}"
display_name_template: "{{ user.name }}"
email_template: "{{ user.email }}"
EOF
# Restart Matrix for changes to take the above configuration
run_command "/federated/bin/stop matrix"
run_command "/federated/bin/start matrix"
echo -ne "done."
}
convert_element() {
#### Convert Element
echo -ne "\n* Converting element.."
convert_generic element
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/element/data/element/element-config.json
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/element/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "element" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_listmonk() {
#### Convert Listmonk
echo -ne "\n* Converting listmonk.."
convert_generic listmonk
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/listmonk/data/listmonk/config.toml
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/listmonk/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "listmonk" "nc -z $SERVICE_IP 9000 &> /dev/null"
# Change app.root_url and other settings to our domain
docker exec postgresql psql -U listmonk -c "update settings set value='\"http://listmonk.$DOMAIN_NEW\"' where key='app.root_url'" &> /dev/null
docker exec postgresql psql -U listmonk -c "update settings set value='\"listmonk <listmonk@listmonk.$DOMAIN_NEW>\"' where key='app.from_email'" &> /dev/null
docker exec postgresql psql -U listmonk -c "update settings set value='[{\"host\": \"mail.$DOMAIN_NEW\", \"port\": 587, \"enabled\": true, \"password\": \"$ADMINPASS\", \"tls_type\": \"STARTTLS\", \"username\": \"$SMTPUSER\", \"max_conns\": 10, \"idle_timeout\": \"15s\", \"wait_timeout\": \"5s\", \"auth_protocol\": \"login\", \"email_headers\": [], \"hello_hostname\": \"\", \"max_msg_retries\": 2, \"tls_skip_verify\": false}, {\"host\": \"smtp.gmail.com\", \"port\": 465, \"enabled\": false, \"password\": \"password\", \"tls_type\": \"TLS\", \"username\": \"username@gmail.com\", \"max_conns\": 10, \"idle_timeout\": \"15s\", \"wait_timeout\": \"5s\", \"auth_protocol\": \"login\", \"email_headers\": [], \"hello_hostname\": \"\", \"max_msg_retries\": 2, \"tls_skip_verify\": false}]' where key='smtp';" &> /dev/null
echo -ne "done."
}
convert_vaultwarden() {
#### Convert Vaultwarden
echo -ne "\n* Converting vaultwarden.."
convert_generic vaultwarden
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/vaultwarden/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "vaultwarden" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_panel() {
#### Convert Panel
echo -ne "\n* Converting panel.."
convert_generic panel
sed -i "s#SITE_NAME=.*#SITE_NAME=$ORG_NEW Panel#g" /federated/apps/panel/.env
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/panel/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "panel" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_wireguard() {
#### Convert Wireguard
echo -ne "\n* Converting wireguard.."
convert_generic wireguard
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/wireguard/data/config/.donoteditthisfile
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/wireguard/data/config/peer1/peer1.conf
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/wireguard/data/config/coredns/Corefile
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/wireguard/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "wireguard" "nc -uvz $SERVICE_IP 51820 &> /dev/null"
echo -ne "done."
}
convert_jitsi() {
#### Convert Jitsi
echo -ne "\n* Converting jitsi.."
convert_generic jitsi
start_service_convert "jitsi" "nc -z 192.168.0.25 443 &> /dev/null"
echo -ne "done."
}
convert_baserow() {
#### Convert Baserow
echo -ne "\n* Converting baserow.."
convert_generic baserow
docker exec postgresql bash -c "psql -U baserow -c \"UPDATE auth_user SET username=REPLACE(username, '@$DOMAIN','@$DOMAIN_NEW') WHERE username LIKE '%@$DOMAIN'\"" &> /dev/null
[ $? -ne 0 ] && fail "Couldn't update auth_user table (username) in baserow"
docker exec postgresql bash -c "psql -U baserow -c \"UPDATE auth_user SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'\"" &> /dev/null
[ $? -ne 0 ] && fail "Couldn't update auth_user table (email) in baserow"
start_service_convert "baserow" "docker exec baserow curl http://localhost:8000 &> /dev/null"
echo -ne "done."
}
convert_gitea() {
#### Convert Gitea
echo -ne "\n* Converting gitea.."
convert_generic gitea
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/gitea/data/data/gitea/conf/app.ini
# Replace users in Gitea postgres database with new domain name
LOWER_DOMAIN_NEW="$(echo $DOMAIN_NEW |tr 'A-Z' 'a-z')"
docker exec postgresql bash -c "psql -U gitea -c \"UPDATE email_address SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'\""
docker exec postgresql bash -c "psql -U gitea -c \"UPDATE email_address SET lower_email=REPLACE(lower_email, '@$DOMAIN', '@$LOWER_DOMAIN_NEW') WHERE lower_email LIKE '%@$DOMAIN'\""
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/gitea/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "gitea" "nc -z $SERVICE_IP 3000 &> /dev/null"
# Delete the current admin and create the admin user with new domain name
# FIXME we used to do
#docker exec --user 1000 gitea bash -c "gitea admin user delete --id 1"
#docker exec --user 1000 gitea gitea admin user create --admin --username gitea --password $ADMINPASS --email admin@$DOMAIN_NEW
# here, but that doesn't seem necessary given we fixed the users above?
# Configure SSO to Authelia
GITEA_CLIENT_SECRET=$(cat /federated/apps/gitea/.gitea.client.secret)
GITEA_AUTH_ID=$(docker exec --user 1000 gitea gitea admin auth list | tail -1 | awk '{ print $1 }')
docker exec --user 1000 gitea gitea admin auth delete --id ${GITEA_AUTH_ID}
docker exec --user 1000 gitea gitea admin auth add-oauth --name "Authelia" --provider "openidConnect" --key "gitea" --secret "$GITEA_CLIENT_SECRET" --auto-discover-url "https://authelia.$DOMAIN_NEW/.well-known/openid-configuration" --skip-local-2fa "true" --scopes "openid email profile" --group-claim-name "groups" --admin-group "admin" --restricted-group "guest"
echo -ne "done."
}
convert_caddy() {
#### Convert Caddy
echo -ne "\n* Converting caddy.."
convert_generic caddy
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/caddy/data/etc/caddy/Caddyfile
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/caddy/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "caddy" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_castopod() {
#### Convert Castopod
echo -ne "\n* Converting castopod.."
convert_generic castopod
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/castopod/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "castopod" "nc -z $SERVICE_IP 8000 &> /dev/null"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD castopod -e \"UPDATE cp_auth_identities SET secret=REPLACE(secret, '@$DOMAIN', '@$DOMAIN_NEW) WHERE secret LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD castopod -e \"UPDATE cp_users SET username=REPLACE(username, '@$DOMAIN', '@$DOMAIN_NEW') WHERE username LIKE '%@$DOMAIN';\""
echo -ne "done."
}
convert_autodiscover() {
#### Convert Autodiscover
echo -ne "\n* Converting autodiscover.."
convert_generic autodiscover
sed -i "s#COMPANY_NAME=.*#COMPANY_NAME=$ORG_NEW#g" /federated/apps/autodiscover/.env
# Add DNS records for auto discovery
docker exec pdns pdnsutil add-record $DOMAIN_NEW autoconfig A 86400 $EXTERNALIP
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW autodiscover A 86400 $EXTERNALIP
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW @ TXT 86400 "\"mailconf=https://autoconfig.$DOMAIN_NEW/mail/config-v1.1.xml\""
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW _imaps._tcp SRV 86400 "0 0 993 mail.$DOMAIN_NEW"
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW _pop3s._tcp SRV 86400 "0 0 995 mail.$DOMAIN_NEW"
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW _imaps._tcp SRV 86400 "0 0 993 mail.$DOMAIN_NEW"
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW _submission._tcp SRV 86400 "0 0 587 $DOMAIN_NEW"
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW _autodiscover._tcp SRV 86400 "0 0 443 autodiscover.$DOMAIN_NEW"
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
docker exec pdns pdnsutil add-record $DOMAIN_NEW _ldap._tcp SRV 86400 "0 0 636 ldap.$DOMAIN_NEW"
[ $? -ne 0 ] && fail "Couldn't add dns record for auto discovery"
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/autodiscover/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "autodiscover" "nc -z $SERVICE_IP 8000 &> /dev/null"
echo -ne "done."
}
convert_wordpress() {
#### Convert Wordpress
echo -ne "\n* Converting wordpress.."
convert_generic wordpress
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/wordpress/data/bitnami/wordpress/wp-config.php
sed -i "s#WORDPRESS_BLOG_NAME=.*#WORDPRESS_BLOG_NAME=$ORG_NEW#g" /federated/apps/wordpress/.env
# This covers option_name='home', 'siteurl' and 'admin_email' (and potentially more)
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD wordpress -e \"UPDATE wp_options SET option_value=REPLACE(option_value, '$DOMAIN', '$DOMAIN_NEW') WHERE option_value LIKE '%$DOMAIN%';\""
# Users
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD wordpress -e \"UPDATE wp_users SET user_login=REPLACE(user_login, '@$DOMAIN', '@$DOMAIN_NEW') WHERE user_login LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD wordpress -e \"UPDATE wp_users SET user_email=REPLACE(user_email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE user_email LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD wordpress -e \"UPDATE wp_usermeta SET meta_value=REPLACE(meta_value, '@$DOMAIN', '@$DOMAIN_NEW') WHERE meta_value LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD wordpress -e \"UPDATE wp_users SET display_name=REPLACE(display_name, '@$DOMAIN', '@$DOMAIN_NEW') WHERE display_name LIKE '%@$DOMAIN';\""
# Fix references in posts
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD wordpress -e \"UPDATE wp_posts SET post_content=REPLACE(post_content, '$DOMAIN', '$DOMAIN_NEW') WHERE post_content LIKE '%$DOMAIN%';\""
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/wordpress/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "wordpress" "nc -z $SERVICE_IP 8080 &> /dev/null"
echo -ne "done."
}
convert_coturn() {
#### Convert Coturn
echo -ne "\n* Converting coturn.."
convert_generic coturn
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/coturn/data/etc/turnserver.conf
sed -i "s#static-auth-secret=.*#static-auth-secret=$COTURN_MATRIX_SECRET#g" /federated/apps/coturn/data/etc/turnserver.conf
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/coturn/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "coturn" "nc -z $SERVICE_IP 3478 &> /dev/null"
echo -ne "done."
}
convert_bookstack() {
#### Convert Bookstack
echo -ne "\n* Converting bookstack.."
convert_generic bookstack
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/bookstack/data/config/www/.env
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD bookstack -e \"UPDATE users SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN';\""
# Setup external_auth_id for each user in bookstack users table
BOOKSTACK_SECRET=$(cat /federated/apps/bookstack/.env | grep "DB_PASS" | awk -F= '{ print $2 }')
# for i in $(docker exec pdnsmysql mariadb -ubookstack -p${BOOKSTACK_SECRET} bookstack -sN -e "select email from users;"); do
# docker exec pdnsmysql mariadb -ubookstack -p${BOOKSTACK_SECRET} bookstack -e "update users set external_auth_id = '$i' where email = '$i'";
# done
LOWER_DOMAIN="$(echo $DOMAIN |tr 'A-Z' 'a-z')"
LOWER_DOMAIN_NEW="$(echo $DOMAIN_NEW |tr 'A-Z' 'a-z')"
docker exec pdnsmysql mariadb -ubookstack -p${BOOKSTACK_SECRET} bookstack -sN -e "UPDATE users SET email=REPLACE(email, '@$LOWER_DOMAIN', '@$LOWER_DOMAIN_NEW') WHERE email LIKE '%@$LOWER_DOMAIN';";
docker exec pdnsmysql mariadb -ubookstack -p${BOOKSTACK_SECRET} bookstack -sN -e "UPDATE users SET external_auth_id=REPLACE(external_auth_id, '@$LOWER_DOMAIN', '@$LOWER_DOMAIN_NEW') WHERE external_auth_id LIKE '%@$LOWER_DOMAIN';";
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/bookstack/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "bookstack" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_freescout() {
#### Convert Freescout
echo -ne "\n* Converting freescout.."
convert_generic freescout
docker exec postgresql bash -c "psql -U freescout -c \"UPDATE users SET email=REPLACE(email, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email LIKE '%@$DOMAIN'\""
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/freescout/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "freescout" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_msp() {
#### Convert MSP
echo -ne "\n* Converting msp.."
convert_generic msp
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/msp/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "msp" "nc -z $SERVICE_IP 3000 &> /dev/null"
echo -ne "done."
}
convert_espocrm() {
#### Convert EspoCRM
echo -ne "\n* Converting espocrm.."
# Grab the SSO client secret for config below before removing espocrm
ESPOCRM_CLIENT_SECRET=$(cat /federated/apps/espocrm/.env | grep ESPOCRM_CONFIG_OIDC_CLIENT_SECRET | awk -F= '{ print $2 }')
ESPOCRM_IMAGE_VERSION=$(cat /federated/apps/espocrm/.env | grep IMAGE_VERSION | awk -F\" '{ print $2 }')
convert_generic espocrm
sed -i "s#$DOMAIN#$DOMAIN_NEW#g;s#$DOMAIN_LDAP_dc#$DOMAIN_NEW_LDAP_dc#g;s#$DOMAIN_LDAP_DC#$DOMAIN_NEW_LDAP_DC#g;s#dc=federatedcomputer,dc=cloud#$DOMAIN_NEW_LDAP_dc#g" /federated/apps/espocrm/data/var/www/html/data/config.php /federated/apps/espocrm/data/var/www/html/data/config-internal.php
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/espocrm/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "espocrm" "nc -z $SERVICE_IP 80 &> /dev/null"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD espocrm -e \"UPDATE user SET user_name=REPLACE(user_name, '@$DOMAIN', '@$DOMAIN_NEW') WHERE user_name LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD espocrm -e \"UPDATE email_account SET email_address=REPLACE(email_address, '@$DOMAIN', '@$DOMAIN_NEW') WHERE email_address LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD espocrm -e \"UPDATE email_account SET username=REPLACE(username, '@$DOMAIN', '@$DOMAIN_NEW') WHERE username LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD espocrm -e \"UPDATE email_account SET smtp_username=REPLACE(smtp_username, '@$DOMAIN', '@$DOMAIN_NEW') WHERE smtp_username LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD espocrm -e \"UPDATE email_address SET name=REPLACE(name, '@$DOMAIN', '@$DOMAIN_NEW') WHERE name LIKE '%@$DOMAIN';\""
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD espocrm -e \"UPDATE email_address SET lower=REPLACE(lower, '@$DOMAIN', '@$DOMAIN_NEW') WHERE lower LIKE '%@$DOMAIN';\""
# FIXME did we catch every possible place for email addresses above?
run_command "/federated/bin/stop espocrm"
run_command "/federated/bin/start espocrm"
echo -ne "done."
}
convert_dashboard() {
#### Convert Dashboard
echo -ne "\n* Converting dashboard.."
convert_generic dashboard
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/dashboard/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "dashboard" "nc -z $SERVICE_IP 8080 &> /dev/null"
echo -ne "done."
}
convert_roundcube() {
#### Convert Roundcube
echo -ne "\n* Converting roundcube.."
convert_generic roundcube
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/roundcube/data/var/www/html/config/config.inc.php
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/roundcube/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "roundcube" "nc -z $SERVICE_IP 80 &> /dev/null"
echo -ne "done."
}
convert_authelia() {
#### Convert Authelia
echo -ne "\n* Converting authelia.."
convert_generic authelia
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/authelia/data/config/configuration.yml
sed -i "s#$DOMAIN#$DOMAIN_NEW#g" /federated/apps/authelia/data/config/idproviders.yml
# Configure SSO to Authelia
# Delete the entries in the pdns settings table
[[ -d "/federated/apps/pdnsmysql/data/var/lib/mysql/pdnsadmin" ]] && POWERDNS_DB="pdnsadmin" || POWERDNS_DB="pdns"
POWERDNS_CLIENT_SECRET=$(docker exec pdnsmysql mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e "select value from setting where name='oidc_oauth_secret';" |tail -n1)
docker exec pdnsmysql mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e "delete from setting where name like '%oidc_oauth%';"
# Insert PowerDNS configuration because we need an initial
# config for Authelia to run
PDNS_MYSQL_COMMAND1="insert into setting (name, value) values (\"oidc_oauth_enabled\", \"True\");insert into setting (name, value) values (\"oidc_oauth_key\", \"powerdns\");"
PDNS_MYSQL_COMMAND2="insert into setting (name, value) values (\"oidc_oauth_scope\", \"openid profile groups email\");insert into setting (name, value) values (\"oidc_oauth_api_url\", \"https://authelia.$DOMAIN_NEW/api/oidc/userinfo\");"
PDNS_MYSQL_COMMAND3="insert into setting (name, value) values (\"oidc_oauth_auto_configure\", \"True\");insert into setting (name, value) values (\"oidc_oauth_metadata_url\", \"https://authelia.$DOMAIN_NEW/.well-known/openid-configuration\");"
PDNS_MYSQL_COMMAND4="insert into setting (name, value) values (\"oidc_oauth_token_url\", \"\");insert into setting (name, value) values (\"oidc_oauth_authorize_url\", \"\");"
PDNS_MYSQL_COMMAND5="insert into setting (name, value) values (\"oidc_oauth_logout_url\", \"https://authelia.$DOMAIN_NEW/logout\");insert into setting (name, value) values (\"oidc_oauth_username\", \"preferred_username\");"
PDNS_MYSQL_COMMAND6="insert into setting (name, value) values (\"oidc_oauth_email\", \"email\");insert into setting (name, value) values (\"oidc_oauth_firstname\", \"preferred_username\");"
PDNS_MYSQL_COMMAND7="insert into setting (name, value) values (\"oidc_oauth_last_name\", \"name\");insert into setting (name, value) values (\"oidc_oauth_account_name_property\", \"preferred_username\");"
PDNS_MYSQL_COMMAND8="insert into setting (name, value) values (\"oidc_oauth_account_description_property\", \"name\");insert into setting (name, value) values (\"oidc_oauth_secret\", \"$POWERDNS_CLIENT_SECRET\");"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND1;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND2;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND3;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND4;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND5;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND6;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND7;'"
docker exec pdnsmysql bash -c "mariadb -uroot -p$MYSQL_ROOTPASSWORD $POWERDNS_DB -e '$PDNS_MYSQL_COMMAND8;'"
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/authelia/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
start_service_convert "authelia" "nc -z $SERVICE_IP 9091 &> /dev/null"
echo -ne "done."
}
convert_jitsiopenid() {
#### Convert JitsiOpenID
echo -ne "\n* Converting jitsiopenid.."
convert_generic jitsiopenid
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/jitsiopenid/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
run_command "/federated/bin/start jitsiopenid"
echo -ne "done."
}
convert_discourse() {
#### Convert Discourse
echo -ne "\n* Converting discourse.."
DISCOURSE_CLIENT_SECRET=$(cat /federated/apps/discourse/.discourse.client.secret)
convert_generic discourse
docker exec postgresql psql -U discourse -c "update users set username='admin@$DOMAIN_NEW' where username='admin@$DOMAIN';" &> /dev/null
docker exec postgresql psql -U discourse -c "update users set username_lower='admin@$DOMAIN_NEW' where username_lower='admin@$DOMAIN';" &> /dev/null
docker exec postgresql psql -U discourse -c "update site_settings set value='discourse@$DOMAIN_NEW' where name='notification_email';" &> /dev/null
docker exec postgresql psql -U discourse -c "update site_settings set value='https://authelia.$DOMAIN_NEW/.well-known/openid-configuration' where name='openid_connect_discovery_document';" &> /dev/null
docker exec postgresql psql -U discourse -c "update site_settings set value='$DISCOURSE_CLIENT_SECRET' where name='openid_connect_client_secret';" &> /dev/null
# Grab the container IP from docker-compose
SERVICE_IP=`grep ipv4_address /federated/apps/discourse/docker-compose.yml | awk '{ print $2 }'`
# Start service with command to make sure it's up before proceeding
run_command "/federated/bin/start discourse"
echo -ne "done."
}
usage() {
echo "$0: <domain.com> <organization name>"
exit 2
}
DNS_DONE=false
if [ "$1" = "-d" -o "$1" = "--dns-done" ]; then
DNS_DONE=true
shift
fi
[ $# != 2 ] && usage
DOMAIN_NEW=$1
ORG_NEW=$2
# Check if DNS works
EXTERNALIP=`dig @resolver4.opendns.com myip.opendns.com +short 2> /dev/null`
[ $? -ne 0 ] && failcheck "Couldn't run dig, dns is not working"
# Setup DOMAIN variables for domain or subdomain
if ! echo $DOMAIN_NEW |grep -q '\.'; then
failcheck "$DOMAIN_NEW is not a valid domain.com or sub.domain.com"
fi
DOMAIN_NEW_LDAP_dc="dc=${DOMAIN_NEW//./,dc=}"
DOMAIN_NEW_LDAP_DC="DC=${DOMAIN_NEW//./,DC=}"
DOMAIN_LDAP_dc="dc=${DOMAIN//./,dc=}"
DOMAIN_LDAP_DC="DC=${DOMAIN//./,DC=}"
ADMINPASS=`cat /federated/bin/.adminpass | head -1`
[[ -d "/federated/apps/ldap" ]] && LDAP_SECRET=`cat /federated/apps/ldap/.ldap.secret`
[[ -d "/federated/apps/pdnsmysql" ]] && MYSQL_ROOTPASSWORD=`cat /federated/apps/pdnsmysql/.env | grep MYSQL_ROOT_PASSWORD | awk -F= '{ print $2 }'`
# Set SMTP user based on if fcore exists
if [[ -d "/federated/apps/ldap" ]]; then
[[ $(docker exec ldap slapcat | grep fcore) ]] && SMTPUSER="fcore" || SMTPUSER="admin"
fi
echo -ne "\n\nConverting Federated Core $DOMAIN to $DOMAIN_NEW.\n\n"
# Key initial steps
if [[ "${PLUS}" != "true" ]]; then
if ! $DNS_DONE; then
check_gluerecords
do_serviceprep_dns
fi
fi
if [[ "${PLUS}" != "true" ]]; then
do_serviceprep_ldap
fi
# Stop all services
/federated/bin/stop all &> /dev/null
# Convert each services in SERVICES list
for i in "${SERVICES[@]}"; do
if [ -d "/federated/apps/$i" ]; then
convert_$i
fi
done