Browse Source

website: deploy website.securedrop.club

from https://lab.securedrop.club/main/website
keep-around/3e0400fddc1d96281bed9154491b7fc6e94b1930
Loïc Dachary 3 years ago
parent
commit
a4b233626c
Signed by: dachary GPG Key ID: 283AFA30CA7F55A4
  1. 2
      inventory/host_vars/website-host/website.yml
  2. 1
      molecule/website/.gitignore
  3. 1
      molecule/website/create.yml
  4. 1
      molecule/website/destroy.yml
  5. 41
      molecule/website/molecule.yml
  6. 11
      molecule/website/playbook.yml
  7. 8
      molecule/website/roles/website/files/website-logrotate
  8. 2
      molecule/website/roles/website/tasks/main.yml
  9. 115
      molecule/website/roles/website/tasks/website.yml
  10. 1
      molecule/website/roles/website/templates/crontab
  11. 14
      molecule/website/roles/website/templates/update-website.sh.j2
  12. 58
      molecule/website/tests/test_icinga.py
  13. 25
      molecule/website/tests/test_website.py
  14. 35
      molecule/website/website-playbook.yml

2
inventory/host_vars/website-host/website.yml

@ -0,0 +1,2 @@
---
website_vhost_fqdn: "{{ domain }}"

1
molecule/website/.gitignore

@ -0,0 +1 @@
secret

1
molecule/website/create.yml

@ -0,0 +1 @@
../infrastructure/create.yml

1
molecule/website/destroy.yml

@ -0,0 +1 @@
../infrastructure/destroy.yml

41
molecule/website/molecule.yml

@ -0,0 +1,41 @@
---
driver:
name: openstack
lint:
name: yamllint
platforms:
- name: bind-host
flavor: "s1-2"
- name: postfix-host
flavor: "s1-2"
- name: icinga-host
flavor: "s1-2"
- name: website-host
flavor: "s1-2"
provisioner:
name: ansible
lint:
name: ansible-lint
env:
# https://github.com/metacloud/molecule/issues/1008 for why ../../.. and ../ only
ANSIBLE_ROLES_PATH: roles:../../../infrastructure/roles:../postfix/roles:../bind/roles:../icinga/roles:../backup/roles:../misc/roles:../packages/roles:../jdauphant.nginx/roles
inventory:
links:
# Path is relative to .molecule folder
group_vars: ../../../inventory/group_vars
host_vars: ../../../inventory/host_vars
scenario:
name: website
test_sequence:
- destroy
- create
- converge
- verify
- destroy
verifier:
name: testinfra
options:
v: True
s: True
lint:
name: flake8

11
molecule/website/playbook.yml

@ -0,0 +1,11 @@
---
- import_playbook: ../misc/sexy-debian-playbook.yml
- import_playbook: ../icinga/test-icinga-playbook.yml
- import_playbook: ../bind/bind-playbook.yml
- import_playbook: ../bind/bind-client-playbook.yml
- import_playbook: ../icinga/icinga-playbook.yml
- import_playbook: ../postfix/postfix-playbook.yml
- import_playbook: ../gitlab/test-real-gitlab-playbook.yml
- import_playbook: website-playbook.yml
- import_playbook: ../misc/commit_etc-playbook.yml

8
molecule/website/roles/website/files/website-logrotate

@ -0,0 +1,8 @@
/var/log/update-website.log {
rotate 12
monthly
compress
missingok
notifempty
create debian debian
}

2
molecule/website/roles/website/tasks/main.yml

@ -0,0 +1,2 @@
---
- import_tasks: website.yml

115
molecule/website/roles/website/tasks/website.yml

@ -0,0 +1,115 @@
---
- name: apt-get install git
apt:
name: git
state: present
- name: apt-get install virtualenv
apt:
name: virtualenv
state: present
- name: apt-get install python-pip
apt:
name: python-pip
state: present
- name: pip install setuptools
pip:
name: setuptools
- name: pip install docker
pip:
name: docker
- name: chown debian /srv
file:
path: /srv
owner: debian
- name: git clone https://lab.securedrop.club/main/website
git:
repo: "https://lab.securedrop.club/main/website"
force: yes
dest: /srv/website
become: False
- name: Allow debian user to use docker without sudo
user:
name: debian
groups: docker
- name: reset ssh connection to be in the docker group
# ugly hack in replacement to
# meta: reset_connection
# The later fails in this way:
# https://github.com/ansible/ansible/issues/27520#issuecomment-321966784
local_action:
module: file
path: "~/.ansible/cp/{{ ansible_host }}-{{ ansible_port }}-{{ ansible_user }}"
state: absent
become: False
- name: apt-get install rsync
apt:
name: rsync
state: present
- apt_repository:
repo: deb http://deb.debian.org/debian/ testing main
state: present
- name: apt-get install hugo
apt:
name: hugo
state: present
- name: /var/www/html is owned by debian
file:
path: /var/www/html
state: directory
owner: debian
- name: Copy update-website.sh
template:
src: update-website.sh.j2
dest: /srv/update-website.sh
owner: debian
mode: "0755"
- name: Copy crontab
template:
src: crontab
dest: /srv/crontab
owner: debian
mode: "0600"
register: crontab
- name: update-website.sh log file
file:
path: /var/log/update-website.log
state: touch
owner: debian
- name: install /etc/logrotate.d/website-logrotate
copy:
src: website-logrotate
dest: /etc/logrotate.d/website-logrotate
- name: Activate crontab
shell: crontab /srv/crontab
when: crontab|changed
become: False
- name: start https-portal
docker_container:
name: https-portal
image: steveltn/https-portal:1
restart_policy: always
ports:
- '80:80'
- '443:443'
env:
DOMAINS: '{{ website_vhost_fqdn }} -> http://{{ website_vhost_fqdn }}:8080, www.{{ website_vhost_fqdn }} -> http://{{ website_vhost_fqdn }}:8080'
STAGE: "{% if with_fake_LE is undefined %}production{% else %}staging{% endif %}"
state: "{% if with_https is defined and with_https == true %}started{% else %}absent{% endif %}"

1
molecule/website/roles/website/templates/crontab

@ -0,0 +1 @@
*/5 * * * * flock /tmp/update-website /srv/update-website.sh >> /var/log/update-website.log 2>&1

14
molecule/website/roles/website/templates/update-website.sh.j2

@ -0,0 +1,14 @@
#!/bin/bash
set -e
echo ======================================================================
date
echo ======================================================================
cd /srv/website
git fetch
git pull
hugo --baseURL="https://{{ website_vhost_fqdn }}/"
rsync -av --delete public/ /var/www/html/

58
molecule/website/tests/test_icinga.py

@ -0,0 +1,58 @@
import urllib3
import re
import requests
import yaml
testinfra_hosts = ['icinga-host']
def get_auth(host):
with host.sudo():
f = host.file("/etc/icinga2/conf.d/api-users.conf")
return (
re.search('ApiUser "(.*)"', f.content_string).group(1),
re.search('password = "(.*)"', f.content_string).group(1)
)
def get_master_address(host):
inventory = yaml.load(open(host.backend.ansible_inventory))
address = inventory['all']['hosts']['icinga-host']['ansible_host']
return address
def sloppy_get(url, headers={}, auth=None):
s = requests.Session()
s.auth = auth
s.headers.update(headers)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
r = s.get(url, verify=False, timeout=5)
r.raise_for_status()
return r
def test_icinga_api_hosts(host):
address = get_master_address(host)
r = sloppy_get(
'https://{address}:5665/v1/objects/hosts/website-host'.format(
address=address),
{'Accept': 'application/json'},
get_auth(host),
)
answer = r.json()
assert len(answer['results']) == 1
assert answer['results'][0]['name'] == 'website-host'
def test_icinga_api_services(host):
address = get_master_address(host)
r = sloppy_get(
'https://{address}:5665/v1/objects/services?host=website-host'.format(
address=address),
{'Accept': 'application/json'},
get_auth(host),
)
answer = r.json()
assert len(answer['results']) > 10
assert len([s for s in answer['results']
if 'website-host!Website' == s['name']]) == 1

25
molecule/website/tests/test_website.py

@ -0,0 +1,25 @@
testinfra_hosts = ['website-host']
def test_website(host):
cmd = host.run("""
set -xe
flock /tmp/update-website \
bash -x /srv/update-website.sh \
>> /var/log/update-website.log 2>&1
grep --quiet -i securedrop /var/www/html/index.html
""")
print(cmd.stdout)
print(cmd.stderr)
assert 0 == cmd.rc
cmd = host.run("""
set -xe
! test -f /var/log/update-website.log.1.gz
sudo /usr/sbin/logrotate --force /etc/logrotate.d/website-logrotate
test -f /var/log/update-website.log.1.gz
test debian = $(stat --format=%U /var/log/update-website.log)
""")
print(cmd.stdout)
print(cmd.stderr)
assert 0 == cmd.rc

35
molecule/website/website-playbook.yml

@ -0,0 +1,35 @@
---
- name: install nginx
hosts: website-host
roles:
- role: jdauphant.nginx
nginx_http_params:
- access_log "/var/log/nginx/access.log"
nginx_sites:
default:
- listen "{% if with_https is defined and with_https == true %}8080{% else %}80{% endif %}"
- server_name _
- root /var/www/html/
tasks:
- name: restart nginx
shell: systemctl restart nginx
become: True
- name: install website
hosts: website-host
roles:
- { role: ansible-role-docker, docker_install_compose: false }
- { role: website }
- role: monitor_http_vhost
http_vhost_name: Website
http_vhost_fqdn: "{{ website_vhost_fqdn }}"
http_vhost_uri: "/"
http_vhost_string: "SecureDrop"
become: True
Loading…
Cancel
Save