Skip to content
Snippets Groups Projects
Verified Commit 51b70bbf authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Working setup with e2e test !

parent ed1a1019
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ funkwhale_media_path: /srv/funkwhale/data/media
funkwhale_static_path: /srv/funkwhale/data/static
funkwhale_music_path: /srv/funkwhale/data/music
funkwhale_config_path: /srv/funkwhale/config
funkwhale_external_storage_enabled: false
funkwhale_username: funkwhale
funkwhale_database_managed: true
funkwhale_database_name: funkwhale
......@@ -18,3 +19,8 @@ funkwhale_settings_module: config.settings.production
funkwhale_env_vars: []
funkwhale_systemd_after: redis.service postgresql.service
funkwhale_systemd_service_name: funkwhale
funkwhale_letsencrypt_certbot_flags:
funkwhale_letsencrypt_enabled: true
funkwhale_letsencrypt_skip_cert: false
funkwhale_ssl_cert_path:
funkwhale_ssl_key_path:
......@@ -3,3 +3,8 @@
service:
name: funkwhale.target
state: restarted
- name: reload nginx
service:
name: nginx
state: reloaded
......@@ -12,3 +12,56 @@ RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y pyth
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi
# Adding test SSL certs
RUN mkdir /certs && \
echo '-----BEGIN CERTIFICATE-----\n\
MIIDqTCCApGgAwIBAgIUBGy73NTCABwZpYk9Xj7O5QlSUd4wDQYJKoZIhvcNAQEL\n\
BQAwZDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\n\
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEdMBsGA1UEAwwUZnVua3doYWxlLnlv\n\
dXJkb21haW4wHhcNMTkwNTEzMDg0MzM2WhcNMjkwNTEwMDg0MzM2WjBkMQswCQYD\n\
VQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQg\n\
V2lkZ2l0cyBQdHkgTHRkMR0wGwYDVQQDDBRmdW5rd2hhbGUueW91cmRvbWFpbjCC\n\
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO7ZdBvEQlUJN5IiKLlxYd9J\n\
ccx74oH2fsLHpESP/uWgvALXxu9XcbtaGAyIIiw5BDoNfew7SKLxx/G5I3Uqs6aI\n\
mPhEiVDW7V8Z3slxQcGY7I5c0RkrlIvcX4pnUfqPHfANQH1rLs6emq2P7MsrQe+P\n\
iIsvJk0BFY+ID4KlxnZzBvuu6gjSucLFtY2/OPV7Rxo9fwflknmGb9GNjWBnlT9e\n\
OQUJRYVGY56m5XU+1C1XRPYFhtBKf0fiO/Hu2MuLKRgY+H7c33BltvOatUo74UzV\n\
ud5X9z75a0Nvivv7elXtR5ThYHfEHODpRm6oLWLc5RUtq3qw7t/PCiEzpySpticC\n\
AwEAAaNTMFEwHQYDVR0OBBYEFPVrtpu6+yY94B6ZQqbu4nQNeH1MMB8GA1UdIwQY\n\
MBaAFPVrtpu6+yY94B6ZQqbu4nQNeH1MMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI\n\
hvcNAQELBQADggEBALmL+8SAPkelsSPLocbjT1I3BQPpBARDds7JA8I+sWW8eRg4\n\
jYJ0tXdKhJoaLoURrqGXT42CPO61shESKVTgmF84S+IXfVHaKySRQ2XbGAC0c2+W\n\
c3nVH3QYEpGR0uINPNpzS/TB0Xiw5vTLu9i8KppgynFa8GzPVFL5U6Cjk/7sbpP+\n\
8EMF1+fj1ol4Unr7NswK4qgZ/e7gvUghCwWUMlbWfn8YAW/Rz8cfofiYBpTLiOmn\n\
3ZnvZpNVSUy7LIBf9hJrnpYZ62YLa3W2mBxvNNDlpt5OuqBn9xJpmzjdwnL5hake\n\
/ofctTHKVVBLDrteZaR3zFJtcnMJBgxrHAnKDxY=\n\
-----END CERTIFICATE-----' > /certs/test.crt && \
echo '-----BEGIN PRIVATE KEY-----\n\
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDu2XQbxEJVCTeS\n\
Iii5cWHfSXHMe+KB9n7Cx6REj/7loLwC18bvV3G7WhgMiCIsOQQ6DX3sO0ii8cfx\n\
uSN1KrOmiJj4RIlQ1u1fGd7JcUHBmOyOXNEZK5SL3F+KZ1H6jx3wDUB9ay7Onpqt\n\
j+zLK0Hvj4iLLyZNARWPiA+CpcZ2cwb7ruoI0rnCxbWNvzj1e0caPX8H5ZJ5hm/R\n\
jY1gZ5U/XjkFCUWFRmOepuV1PtQtV0T2BYbQSn9H4jvx7tjLiykYGPh+3N9wZbbz\n\
mrVKO+FM1bneV/c++WtDb4r7+3pV7UeU4WB3xBzg6UZuqC1i3OUVLat6sO7fzwoh\n\
M6ckqbYnAgMBAAECggEBAOcJHr+xEryworlPI3dljldu8o3qk4pFBg6hEGtlohk6\n\
ZkKVuA9R1Wh1WGfe0rdWG5mP7WsxWSyMlWxjOkIeoRIIdXdIzE6O56MjIhZW4FVE\n\
+CUo8PXY6uJys1PsZybngvztxKDMqcUhM9uJKXLJEAmLHHgNjo3T66gf42jrs9Jj\n\
yRFtX7P2+WkGtiELiHavnwebFu7QalsbVnIM2IpkqM3EeCkN2Mesg8UjbGAaC04d\n\
QQrgzwllRfGGz00bcW7+UM9Qvuo4ySycagkJsjUwg27Fa2bYn0nwKckmoZdqtFZi\n\
T5MNF17/69x3KtfP4B/z/DmpIpFl3sx3DTNJZGdunykCgYEA/z67wEaLTE6eaYS6\n\
ZMpeUgv/55sdfnbGwxJPBum28Pd9re+7wmaUHVqant9bskTKjFUTpzSkG4FMbhW4\n\
QzoyS9xb946dZ86xIpcHdWjMRz1H+WoHyFQMc3FJL3k5bu5O0bhGlkBv9Lw6sB58\n\
mM4TQhvCYTo4gu/CdwbipcAnBpsCgYEA745OQjKETa0kOi7Rl8IynaVL+lCyo11A\n\
mGaIoTVVVb8HtghPwQ2gE3tGZJNqApMXy61EKpL+oBB3hYjaAxjJ6L1uHEk1d4Vh\n\
5ZHtH/2YnL20vrJVVenNGlnkP1sFGPT6Ik/WwtFNzhyiLy3Yh2m6D2dzAJU/q6w/\n\
JME+yjfQgWUCgYEA3HQ2fU9wqKuOrtxwkPUomfy7PjL/OmckLP/3OaVK2L0p070n\n\
kjQ+4UuMGIQaEtLPjn08yEHzK751YO9pgscVAeiFlj+bPDmNTK7dRk8JgM4xB/7I\n\
UgIl7t99sn8lV+aENSbP8J4fFGYu2ka6ns/+Wi7XqFo8zPqAH4XW5AoeqtkCgYEA\n\
g6ueTDhkDCXcwbY2Mcnl9EyExGNSrQR2ms3Qz3r3GphTbrSG0b/hepPJj0KPhDbB\n\
X4wu6Y++MNCcQWOFISqg4DIusZFzt+wycPKSeYD0P0Luc9qlmQFXYOKD2Gb5GEye\n\
p/lmO9K7h0ypwHDckSGFyS29QlbGll+onVUyZAflrRkCgYBJtGOKfwZ8Ws82qzYC\n\
un5cpBQknAOOZaGsPY7BbtIK0/zG66mearYOeo9TxJZgL+hDCL8is7qcGXRGcA5J\n\
5RdqyJ6Ex1hXyc1cnIXXOrSDFVobA2/QMiAZ2kDSW/DkRHwJNDWVtwnG3HG4vEqb\n\
FE/Prv7XTK6n66CPuThoeox2iQ==\n\
-----END PRIVATE KEY-----\n' > /certs/test.key
......@@ -6,11 +6,16 @@
# https://github.com/ansible/molecule/issues/1567#issuecomment-436876722
- role: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}"
vars:
funkwhale_letsencrypt_email: test-certbot@yourdomain.funkwhale
funkwhale_letsencrypt_skip_cert: true
# funkwhale_letsencrypt_enabled: false
funkwhale_ssl_cert_path: /certs/test.crt
funkwhale_ssl_key_path: /certs/test.key
funkwhale_hostname: yourdomain.funkwhale
funkwhale_protocol: https
funkwhale_version: 0.19.0-rc2
funkwhale_env_vars:
- EMAIL_CONFIG=smtp+tls://user@:password@youremail.host:587
- DEFAULT_FROM_EMAIL=noreply@yourdomain
- DEFAULT_FROM_EMAIL=noreply@yourdomain.funkwhale
- ADDITIONAL_VAR=1
- ADDITIONAL_VAR=2
import json
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
......@@ -129,3 +129,28 @@ def test_funkwhale_services(service, host):
service = host.service(service)
assert service.is_running
assert service.is_enabled
def test_certbot_auto_installed(host):
assert host.find_command("certbot-auto") == "/usr/local/bin/certbot-auto"
def test_nginx_configuration(host):
f = host.file("/etc/nginx/sites-enabled/yourdomain.funkwhale.conf")
assert f.exists is True
content = f.content.decode()
assert "ssl_certificate /certs/test.crt;" in content
assert "ssl_certificate_key /certs/test.key;" in content
def test_e2e_front(host):
command = 'curl -k https://localhost --header "Host: yourdomain.funkwhale"'
result = host.run(command)
assert '<meta content="Funkwhale" property="og:site_name" />' in result.stdout
def test_e2e_api(host):
command = 'curl -k https://localhost/api/v1/instance/nodeinfo/2.0/ --header "Host: yourdomain.funkwhale"'
payload = host.run(command).stdout
data = json.loads(payload)
assert data["software"]["version"] == "0.19.0-rc2"
......@@ -7,7 +7,55 @@
- nginx
- name: "Start Nginx"
become: true
when: funkwhale_nginx_managed
service:
name: nginx
state: started
# from https://gist.github.com/mattiaslundberg/ba214a35060d3c8603e9b1ec8627d349
- name: "Download certbot-auto"
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled
become: true
get_url:
url: https://dl.eff.org/certbot-auto
dest: /usr/local/bin/certbot-auto
mode: 0750
- name: "Install certbot using certbot-auto"
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled
become: true
command: certbot-auto --install-only -n -v
- name: Create letsencrypt certificate
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not funkwhale_letsencrypt_skip_cert
become: true
command: certbot-auto -v -n certonly --nginx -m {{ funkwhale_letsencrypt_email }} --agree-tos -d {{ funkwhale_hostname }} {{ funkwhale_letsencrypt_certbot_flags }}
args:
creates: /etc/letsencrypt/live/{{ funkwhale_hostname }}
- name: Add letsencrypt cronjob for cert renewal
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not funkwhale_letsencrypt_skip_cert
become: true
cron:
name: funkwhale_letsencrypt_renewal
special_time: weekly
job: certbot-auto -v -n --renew certonly --nginx -m {{ funkwhale_letsencrypt_email }} --agree-tos -d {{ funkwhale_hostname }} {{ funkwhale_letsencrypt_certbot_flags }}
- name: "Create funkwhale proxy file"
when: funkwhale_nginx_managed
become: true
template:
src: funkwhale_proxy.conf.j2
dest: "/etc/nginx/funkwhale_proxy.conf"
notify:
- reload nginx
- name: "Create funkwhale vhost file"
when: funkwhale_nginx_managed
become: true
template:
src: nginx.conf.j2
dest: "/etc/nginx/sites-enabled/{{ funkwhale_hostname }}.conf"
notify:
- reload nginx
......@@ -18,3 +18,5 @@
- "libmagic-dev"
- "libpq-dev"
- "postgresql-client"
# not strictly needed but useful
- "curl"
# global proxy conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Port $server_port;
proxy_redirect off;
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# {{ ansible_managed }}
{% if funkwhale_protocol == 'https' %}
server {
listen 80;
server_name {{ funkwhale_hostname }};
{% if funkwhale_letsencrypt_enabled %}
location /.well-known/acme-challenge {
root /var/www/letsencrypt;
try_files $uri $uri/ =404;
}
{% endif %}
location / {
rewrite ^ https://{{ funkwhale_hostname }}$request_uri? permanent;
}
}
{% endif %}
# required for websocket support
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen {% if funkwhale_protocol == 'https' %}443 ssl{% else %}80{% endif %};
server_name {{ funkwhale_hostname }};
{% if funkwhale_letsencrypt_enabled %}
location /.well-known/acme-challenge {
root /var/www/letsencrypt;
try_files $uri $uri/ =404;
}
{% endif %}
{% if funkwhale_protocol == 'https' %}
{% if funkwhale_ssl_key_path %}
ssl_certificate {{ funkwhale_ssl_cert_path }};
ssl_certificate_key {{ funkwhale_ssl_key_path }};
{% else %}
ssl_certificate /ect/lectsencrypt/live/{{ funkwhale_hostname }}/fullchain.pem;
ssl_certificate_key /ect/lectsencrypt/live/{{ funkwhale_hostname }}/privkey.pem;
{% endif %}
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA";
add_header Strict-Transport-Security "max-age=31536000";
{% endif %}
root {{ funkwhale_install_path }}/front/dist;
# compression settings
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
application/javascript
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
# end of compression settings
location / {
include /etc/nginx/funkwhale_proxy.conf;
# this is needed if you have file import via upload enabled
client_max_body_size {{ funkwhale_nginx_max_body_size }};
proxy_pass http://{{ funkwhale_api_ip }}:{{ funkwhale_api_port }}/;
}
location /front/ {
alias {{ funkwhale_install_path }}/front/dist/;
expires 30d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location /federation/ {
include /etc/nginx/funkwhale_proxy.conf;
proxy_pass http://{{ funkwhale_api_ip }}:{{ funkwhale_api_port }}/federation/;
}
# You can comment this if you do not plan to use the Subsonic API
location /rest/ {
include /etc/nginx/funkwhale_proxy.conf;
proxy_pass http://{{ funkwhale_api_ip }}:{{ funkwhale_api_port }}/api/subsonic/rest/;
}
location /.well-known/ {
include /etc/nginx/funkwhale_proxy.conf;
proxy_pass http://{{ funkwhale_api_ip }}:{{ funkwhale_api_port }}/.well-known/;
}
location /media/ {
alias {{ funkwhale_media_path }}/;
}
{% if funkwhale_external_storage_enabled %}
# Comment the previous location and uncomment this one if you're storing
# media files in a S3 bucket
location ~ /_protected/media/(.+) {
internal;
proxy_pass $1;
}
{% else %}
location /_protected/media {
# this is an internal location that is used to serve
# audio files once correct permission / authentication
# has been checked on API side
internal;
alias {{ funkwhale_media_path }};
}
{% endif %}
location /_protected/music {
# this is an internal location that is used to serve
# audio files once correct permission / authentication
# has been checked on API side
# Set this to the same value as your MUSIC_DIRECTORY_PATH setting
internal;
alias {{ funkwhale_music_path }};
}
location /staticfiles/ {
# django static files
alias {{ funkwhale_static_path }}/;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment