Browse Source

add option to use Docker instead of VM (#16)

Co-authored-by: Max Erenberg <>
Co-authored-by: Rio <r345liu@localhost>
Reviewed-on: #16
Co-authored-by: Max Erenberg <merenber@csclub.uwaterloo.ca>
Co-committed-by: Max Erenberg <merenber@csclub.uwaterloo.ca>
pull/20/head
Max Erenberg 11 months ago
parent
commit
de18a9f293
  1. 43
      .drone/auth1-setup.sh
  2. 13
      .drone/coffee-setup.sh
  3. 60
      .drone/common.sh
  4. 31
      .drone/data.ldif
  5. 21
      .drone/mail-setup.sh
  6. 67
      .drone/phosphoric-acid-setup.sh
  7. 17
      .drone/supervise.sh
  8. 303
      .drone/uwldap_data.ldif
  9. 59
      README.md
  10. 44
      docker-compose.yml
  11. 16
      docker-entrypoint.sh
  12. 14
      tests/MockMailmanServer.py
  13. 10
      tests/MockSMTPServer.py
  14. 4
      tests/ceod_dev.ini
  15. 4
      tests/ceod_test_local.ini

43
.drone/auth1-setup.sh

@ -7,17 +7,22 @@ set -ex
# set FQDN in /etc/hosts
add_fqdn_to_hosts $(get_ip_addr $(hostname)) auth1
# I'm not sure why, but we also need to remove the hosts entry for the
# container's real hostname, otherwise slapd only looks for the principal
# ldap/<container hostname> (this is with the sasl-host option)
sed -E "/\\b$(hostname)\\b/d" /etc/hosts > /tmp/hosts
cat /tmp/hosts > /etc/hosts
rm /tmp/hosts
if [ -n "$CI" ]; then
# I'm not sure why, but we also need to remove the hosts entry for the
# container's real hostname, otherwise slapd only looks for the principal
# ldap/<container hostname> (this is with the sasl-host option)
sed -E "/\\b$(hostname)\\b/d" /etc/hosts > /tmp/hosts
cat /tmp/hosts > /etc/hosts
rm /tmp/hosts
fi
export DEBIAN_FRONTEND=noninteractive
apt update
apt install -y psmisc
# If we don't do this then OpenLDAP uses a lot of RAM
ulimit -n 1024
# LDAP
apt install -y --no-install-recommends slapd ldap-utils libnss-ldapd sudo-ldap
# `service slapd stop` doesn't seem to work
@ -40,6 +45,13 @@ sed -E -i 's/^base .*$/base dc=csclub,dc=internal/' /etc/nslcd.conf
cp .drone/nsswitch.conf /etc/nsswitch.conf
service nslcd start
ldapadd -c -f .drone/data.ldif -Y EXTERNAL -H ldapi:///
if [ -z "$CI" ]; then
ldapadd -c -f .drone/uwldap_data.ldif -Y EXTERNAL -H ldapi:/// || true
# setup ldapvi for convenience
apt install -y vim ldapvi
echo 'export EDITOR=vim' >> /root/.bashrc
echo 'alias ldapvi="ldapvi -Y EXTERNAL -h ldapi:///"' >> /root/.bashrc
fi
# KERBEROS
apt install -y krb5-admin-server krb5-user libpam-krb5 libsasl2-modules-gssapi-mit sasl2-bin
@ -58,6 +70,7 @@ cat <<EOF | kadmin.local
addpol -minlength 4 default
addprinc -pw krb5 sysadmin/admin
addprinc -pw krb5 ctdalek
addprinc -pw krb5 exec1
addprinc -pw krb5 regular1
addprinc -randkey host/auth1.csclub.internal
addprinc -randkey ldap/auth1.csclub.internal
@ -76,8 +89,20 @@ EOF
sed -E -i 's/^START=.*$/START=yes/' /etc/default/saslauthd
sed -E -i 's/^MECHANISMS=.*$/MECHANISMS="kerberos5"/' /etc/default/saslauthd
service saslauthd start
killall slapd && sleep 0.5 && service slapd start
while true; do
killall slapd
sleep 1
if service slapd start; then
break
fi
done
# sync with phosphoric-acid
apt install -y netcat-openbsd
nc -l 0.0.0.0 9000
# sync with phosphoric-acid
nc -l 0.0.0.0 9000 &
if [ -z "$CI" ]; then
# sync with coffee
nc -l 0.0.0.0 9001 &
# sync with mail
nc -l 0.0.0.0 9002 &
fi

13
.drone/coffee-setup.sh

@ -6,20 +6,23 @@ set -ex
# set FQDN in /etc/hosts
add_fqdn_to_hosts $(get_ip_addr $(hostname)) coffee
add_fqdn_to_hosts $(get_ip_addr auth1) auth1
export DEBIAN_FRONTEND=noninteractive
apt update
apt install --no-install-recommends -y default-mysql-server postgresql
# MYSQL
service mysql stop
sed -E -i 's/^(bind-address[[:space:]]+= 127.0.0.1)$/#\1/' /etc/mysql/mariadb.conf.d/50-server.cnf
service mysql start
cat <<EOF | mysql
CREATE USER 'mysql' IDENTIFIED BY 'mysql';
CREATE USER IF NOT EXISTS 'mysql' IDENTIFIED BY 'mysql';
GRANT ALL PRIVILEGES ON *.* TO 'mysql' WITH GRANT OPTION;
EOF
# POSTGRESQL
service postgresql stop
POSTGRES_DIR=/etc/postgresql/11/main
cat <<EOF > $POSTGRES_DIR/pg_hba.conf
@ -43,6 +46,10 @@ REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
EOF" postgres
# sync with phosphoric-acid
apt install -y netcat-openbsd
nc -l 0.0.0.0 9000
if [ -z "$CI" ]; then
auth_setup coffee
fi
# sync with phosphoric-acid
nc -l 0.0.0.0 9000 &

60
.drone/common.sh

@ -15,3 +15,63 @@ add_fqdn_to_hosts() {
rm /tmp/hosts
echo "$ip_addr $hostname.csclub.internal $hostname" >> /etc/hosts
}
sync_with() {
host=$1
port=9000
if [ $# -eq 2 ]; then
port=$2
fi
synced=false
# give it 5 minutes
for i in {1..60}; do
if nc -vz $host $port ; then
synced=true
break
fi
sleep 5
done
test $synced = true
}
auth_setup() {
hostname=$1
# LDAP
apt install -y --no-install-recommends libnss-ldapd
service nslcd stop || true
cp .drone/ldap.conf /etc/ldap/ldap.conf
grep -Eq '^map group member uniqueMember$' /etc/nslcd.conf || \
echo 'map group member uniqueMember' >> /etc/nslcd.conf
sed -E -i 's/^uri .*$/uri ldap:\/\/auth1.csclub.internal/' /etc/nslcd.conf
sed -E -i 's/^base .*$/base dc=csclub,dc=internal/' /etc/nslcd.conf
cp .drone/nsswitch.conf /etc/nsswitch.conf
# KERBEROS
apt install -y krb5-user libpam-krb5 libsasl2-modules-gssapi-mit
cp .drone/krb5.conf /etc/krb5.conf
if [ $hostname = phosphoric-acid ]; then
sync_port=9000
elif [ $hostname = coffee ]; then
sync_port=9001
else
sync_port=9002
fi
sync_with auth1 $sync_port
rm -f /etc/krb5.keytab
cat <<EOF | kadmin -p sysadmin/admin -w krb5
addprinc -randkey host/$hostname.csclub.internal
ktadd host/$hostname.csclub.internal
addprinc -randkey ceod/$hostname.csclub.internal
ktadd ceod/$hostname.csclub.internal
EOF
if [ $hostname = phosphoric-acid ]; then
cat <<EOF | kadmin -p sysadmin/admin -w krb5
addprinc -randkey ceod/admin
ktadd ceod/admin
EOF
fi
service nslcd start
}

31
.drone/data.ldif

@ -123,3 +123,34 @@ objectClass: group
objectClass: posixGroup
cn: regular1
gidNumber: 20002
dn: uid=exec1,ou=People,dc=csclub,dc=internal
cn: Regular One
userPassword: {SASL}exec1@CSCLUB.INTERNAL
loginShell: /bin/bash
homeDirectory: /users/exec1
uid: exec1
uidNumber: 20003
gidNumber: 20003
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: member
program: MAT/Mathematics Computer Science
term: s2021
dn: cn=exec1,ou=Group,dc=csclub,dc=internal
objectClass: top
objectClass: group
objectClass: posixGroup
cn: exec1
gidNumber: 20003
dn: cn=exec,ou=Group,dc=csclub,dc=internal
objectClass: top
objectClass: group
objectClass: posixGroup
cn: exec
gidNumber: 10013
uniqueMember: uid=exec1,ou=People,dc=csclub,dc=internal

21
.drone/mail-setup.sh

@ -0,0 +1,21 @@
#!/bin/bash
set -ex
. .drone/common.sh
# set FQDN in /etc/hosts
add_fqdn_to_hosts $(get_ip_addr $(hostname)) mail
add_fqdn_to_hosts $(get_ip_addr auth1) auth1
[ -f venv/bin/activate ] && . venv/bin/activate
python tests/MockMailmanServer.py &
python tests/MockSMTPServer.py &
export DEBIAN_FRONTEND=noninteractive
apt update
apt install -y netcat-openbsd
auth_setup mail
# sync with phosphoric-acid
nc -l 0.0.0.0 9000 &

67
.drone/phosphoric-acid-setup.sh

@ -4,61 +4,32 @@ set -ex
. .drone/common.sh
sync_with() {
host=$1
synced=false
# give it 5 minutes
for i in {1..60}; do
if nc -vz $host 9000 ; then
synced=true
break
fi
sleep 5
done
test $synced = true
}
# set FQDN in /etc/hosts
add_fqdn_to_hosts $(get_ip_addr $(hostname)) phosphoric-acid
add_fqdn_to_hosts $(get_ip_addr auth1) auth1
add_fqdn_to_hosts $(get_ip_addr coffee) coffee
add_fqdn_to_hosts "$(get_ip_addr $(hostname))" phosphoric-acid
add_fqdn_to_hosts "$(get_ip_addr auth1)" auth1
add_fqdn_to_hosts "$(get_ip_addr coffee)" coffee
# mail container doesn't run in CI
if [ -z "$CI" ]; then
add_fqdn_to_hosts $(get_ip_addr mail) mail
fi
export DEBIAN_FRONTEND=noninteractive
apt update
# LDAP
apt install -y --no-install-recommends libnss-ldapd
service nslcd stop || true
cp .drone/ldap.conf /etc/ldap/ldap.conf
grep -Eq '^map group member uniqueMember$' /etc/nslcd.conf || \
echo 'map group member uniqueMember' >> /etc/nslcd.conf
sed -E -i 's/^uri .*$/uri ldap:\/\/auth1.csclub.internal/' /etc/nslcd.conf
sed -E -i 's/^base .*$/base dc=csclub,dc=internal/' /etc/nslcd.conf
cp .drone/nsswitch.conf /etc/nsswitch.conf
# KERBEROS
apt install -y krb5-user libpam-krb5 libsasl2-modules-gssapi-mit
cp .drone/krb5.conf /etc/krb5.conf
apt install -y netcat-openbsd
sync_with auth1
rm -f /etc/krb5.keytab
cat <<EOF | kadmin -p sysadmin/admin
krb5
addprinc -randkey host/phosphoric-acid.csclub.internal
ktadd host/phosphoric-acid.csclub.internal
addprinc -randkey ceod/phosphoric-acid.csclub.internal
ktadd ceod/phosphoric-acid.csclub.internal
addprinc -randkey ceod/admin
ktadd ceod/admin
EOF
service nslcd start
sync_with coffee
auth_setup phosphoric-acid
# initialize the skel directory
shopt -s dotglob
mkdir -p /users/skel
cp /etc/skel/* /users/skel/
# create directories for users
for user in ctdalek regular1 exec1; do
mkdir -p /users/$user
chown $user:$user /users/$user
done
sync_with coffee
if [ -z "$CI" ]; then
sync_with mail
fi

17
.drone/supervise.sh

@ -0,0 +1,17 @@
#!/bin/sh
# A script that supervises a program. The program is restarted TIMEOUT second after it exits.
# SIGHUP restarts the program
# SIGTERM and SIGINT stops the program
TIMEOUT=1
running=1
trap 'kill -TERM $! 2>/dev/null' HUP
trap 'running=0; kill -TERM $! 2>/dev/null' TERM INT
trap 'running=0; kill -KILL $! 2>/dev/null' EXIT
while [ "$running" = 1 ]; do
"$@" &
wait
sleep "$TIMEOUT"
done

303
.drone/uwldap_data.ldif

@ -0,0 +1,303 @@
dn: ou=UWLDAP,dc=csclub,dc=internal
objectClass: organizationalUnit
ou: UWLDAP
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
displayName: Calum Dalek
givenName: Calum
sn: Dalek
cn: Calum Dalek
ou: MAT/Mathematics Computer Science
mailLocalAddress: ctdalek@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: ctdalek
mail: ctdalek@uwaterloo.internal
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular One
givenName: Regular
sn: One
cn: Regular One
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular1
mail: regular1@uwaterloo.internal
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular Two
givenName: Regular
sn: Two
cn: Regular Two
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular2@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular2
mail: regular2@uwaterloo.internal
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec One
givenName: Exec
sn: One
cn: Exec One
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec1
mail: exec1@uwaterloo.internal
dn: uid=exec2,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec Two
givenName: Exec
sn: Two
cn: Exec Two
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec2@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec2
mail: exec2@uwaterloo.internal
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
displayName: Calum Dalek
givenName: Calum
sn: Dalek
cn: Calum Dalek
ou: MAT/Mathematics Computer Science
mailLocalAddress: ctdalek@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: ctdalek
mail: ctdalek@uwaterloo.internal
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular One
givenName: Regular
sn: One
cn: Regular One
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular1
mail: regular1@uwaterloo.internal
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular Two
givenName: Regular
sn: Two
cn: Regular Two
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular2@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular2
mail: regular2@uwaterloo.internal
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec One
givenName: Exec
sn: One
cn: Exec One
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec1
mail: exec1@uwaterloo.internal
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
displayName: Calum Dalek
givenName: Calum
sn: Dalek
cn: Calum Dalek
ou: MAT/Mathematics Computer Science
mailLocalAddress: ctdalek@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: ctdalek
mail: ctdalek@uwaterloo.internal
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular One
givenName: Regular
sn: One
cn: Regular One
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular1
mail: regular1@uwaterloo.internal
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular Two
givenName: Regular
sn: Two
cn: Regular Two
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular2@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular2
mail: regular2@uwaterloo.internal
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec One
givenName: Exec
sn: One
cn: Exec One
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec1
mail: exec1@uwaterloo.internal
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
displayName: Calum Dalek
givenName: Calum
sn: Dalek
cn: Calum Dalek
ou: MAT/Mathematics Computer Science
mailLocalAddress: ctdalek@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: ctdalek
mail: ctdalek@uwaterloo.internal
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular One
givenName: Regular
sn: One
cn: Regular One
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular1
mail: regular1@uwaterloo.internal
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular Two
givenName: Regular
sn: Two
cn: Regular Two
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular2@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular2
mail: regular2@uwaterloo.internal
dn: uid=regular3,ou=UWLDAP,dc=csclub,dc=internal
displayName: Regular Three
givenName: Regular
sn: Three
cn: Regular Three
ou: MAT/Mathematics Computer Science
mailLocalAddress: regular3@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: regular3
mail: regular3@uwaterloo.internal
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec One
givenName: Exec
sn: One
cn: Exec One
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec1@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec1
mail: exec1@uwaterloo.internal
dn: uid=exec2,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec Two
givenName: Exec
sn: Two
cn: Exec Two
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec2@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec2
mail: exec2@uwaterloo.internal
dn: uid=exec3,ou=UWLDAP,dc=csclub,dc=internal
displayName: Exec Three
givenName: Exec
sn: Three
cn: Exec Three
ou: MAT/Mathematics Computer Science
mailLocalAddress: exec3@uwaterloo.internal
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: exec3
mail: exec3@uwaterloo.internal

59
README.md

@ -6,13 +6,54 @@ club accounts and memberships. See [architecture.md](architecture.md) for an
overview of its architecture.
## Development
First, make sure that you have installed the
### Docker
If you are not modifying code related to email or Mailman, then you may use
Docker containers instead, which are much easier to work with than the VM.
First, make sure you create the virtualenv:
```sh
docker run --rm -v "$PWD:$PWD" -w "$PWD" -u $(id -u):$(id -g) python:3.7-buster \
sh -c 'python -m venv venv && . venv/bin/activate && pip install -r requirements.txt -r dev-requirements.txt'
```
Then bring up the containers:
```sh
docker-compose up -d # or without -d to run in the foreground
```
This will create some containers with the bare minimum necessary for ceod to
run, and start ceod on each of phosphoric-acid, mail, and coffee container.
You can check the containers status using:
```sh
docker-compose logs -f
```
To use ceo, run the following:
```sh
docker-compose exec phosphoric-acid bash
su ctdalek
. venv/bin/activate
python -m ceo # the password is krb5
```
This should bring up the TUI.
Normally, ceod should autoamtically restart when the source files are changed.
To manually restart the service, run:
```sh
docker-compose kill -s SIGHUP phosphoric-acid
```
To stop the containers, run:
```sh
docker-compose down
```
Alternatively, if you started docker-compose in the foreground, just press Ctrl-C.
### VM
If you need the full environment running in VM, follow the guide on
[syscom dev environment](https://git.uwaterloo.ca/csc/syscom-dev-environment).
This will setup all of the services needed for ceo to work. You should clone
this repo in the phosphoric-acid container under ctdalek's home directory; you
will then be able to access it from any container thanks to NFS.
### Environment setup
Once you have the dev environment setup, there are a few more steps you'll
need to do for ceo.
@ -129,7 +170,7 @@ pip install -r requirements.txt
pip install -r dev-requirements.txt
```
## Running the application
#### Running the application
ceod is a distributed application, with instances on different hosts offering
different services.
Therefore, you will need to run ceod on multiple hosts. Currently, those are
@ -148,8 +189,16 @@ is running. Stop the flask app (Ctrl-C), run `clear_cache.sh`, then
restart the app.
## Interacting with the application
The client part of ceo hasn't been written yet, so we'll use curl to
interact with ceod for now.
To use the TUI:
```
python -m ceo
```
To use the CLI:
```
python -m ceo --help
```
Alternatively, you may use curl to send HTTP requests.
ceod uses [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) for authentication,
and TLS for confidentiality and integrity. In development mode, TLS can be

44
docker-compose.yml

@ -0,0 +1,44 @@
version: "3.6"
x-common: &common
image: python:3.7-buster
volumes:
- .:$PWD
environment:
FLASK_APP: ceod.api
FLASK_ENV: development
working_dir: $PWD
entrypoint:
- ./docker-entrypoint.sh
services:
auth1:
<<: *common
image: debian:buster
hostname: auth1
command: auth1
coffee:
<<: *common
command: coffee
hostname: coffee
depends_on:
- auth1
mail:
<<: *common
command: mail
hostname: mail
depends_on:
- auth1
phosphoric-acid:
<<: *common
command: phosphoric-acid
hostname: phosphoric-acid
depends_on:
- auth1
- coffee
- mail
# vim: expandtab sw=2 ts=2

16
docker-entrypoint.sh

@ -0,0 +1,16 @@
#!/bin/sh -e
if ! [ -d venv ]; then
echo "You need to create the virtualenv first!" >&2
exit 1
fi
host="$1"
[ -x ".drone/$host-setup.sh" ] && ".drone/$host-setup.sh"
if [ "$host" = auth1 ]; then
exec sleep infinity
else
. venv/bin/activate
exec .drone/supervise.sh flask run -h 0.0.0.0 -p 9987
fi

14
tests/MockMailmanServer.py

@ -4,11 +4,12 @@ from aiohttp import web
class MockMailmanServer:
def __init__(self):
def __init__(self, port=8001, prefix='/3.1'):
self.port = port
self.app = web.Application()
self.app.add_routes([
web.post('/members', self.subscribe),
web.delete('/lists/{mailing_list}/member/{address}', self.unsubscribe),
web.post(prefix + '/members', self.subscribe),
web.delete(prefix + '/lists/{mailing_list}/member/{address}', self.unsubscribe),
])
self.runner = web.AppRunner(self.app)
self.loop = asyncio.new_event_loop()
@ -24,7 +25,7 @@ class MockMailmanServer:
def _start_loop(self):
asyncio.set_event_loop(self.loop)
self.loop.run_until_complete(self.runner.setup())
site = web.TCPSite(self.runner, '127.0.0.1', 8002)
site = web.TCPSite(self.runner, '127.0.0.1', self.port)
self.loop.run_until_complete(site.start())
self.loop.run_forever()
@ -67,3 +68,8 @@ class MockMailmanServer:
}, status=404)
subscribers.remove(subscriber)
return web.json_response({'status': 'OK'})
if __name__ == '__main__':
server = MockMailmanServer()
server.start()

10
tests/MockSMTPServer.py

@ -1,3 +1,6 @@
import os
import time
from aiosmtpd.controller import Controller
@ -25,3 +28,10 @@ class MockHandler:
}
self.mock_server.messages.append(msg)
return '250 Message accepted for delivery'
if __name__ == '__main__':
assert os.geteuid() == 0
server = MockSMTPServer('0.0.0.0', 25)
server.start()
time.sleep(1e6)

4
tests/ceod_dev.ini

@ -20,8 +20,8 @@ groups_base = ou=Group,dc=csclub,dc=internal
sudo_base = ou=SUDOers,dc=csclub,dc=internal
[uwldap]
server_url = ldap://uwldap.uwaterloo.ca
base = dc=uwaterloo,dc=ca
server_url = ldap://auth1.csclub.internal
base = ou=UWLDAP,dc=csclub,dc=internal
[members]
min_id = 20001

4
tests/ceod_test_local.ini

@ -9,7 +9,7 @@ fs_root_host = phosphoric-acid
mailman_host = phosphoric-acid
database_host = phosphoric-acid
use_https = false
port = 9987
port = 9988
[ldap]
admin_principal = ceod/admin
@ -40,7 +40,7 @@ smtp_url = smtp://localhost:8025
smtp_starttls = false
[mailman3]
api_base_url = http://localhost:8002
api_base_url = http://localhost:8001/3.1
api_username = restadmin
api_password = mailman3
new_member_list = csc-general

Loading…
Cancel
Save