diff --git a/.zuul.yaml b/.zuul.d/zuul.yaml
similarity index 68%
rename from .zuul.yaml
rename to .zuul.d/zuul.yaml
index 8aadcf2..d17ecf2 100644
--- a/.zuul.yaml
+++ b/.zuul.d/zuul.yaml
@@ -51,6 +51,34 @@
- name: github.com/ansible/ansible
override-checkout: stable-2.6
+- job:
+ name: ara-server-role-integration-base
+ parent: base
+ files:
+ - playbooks/*
+ - roles/ara_frontend_nginx/*
+ - roles/ara_server/*
+ - ara/*
+ - tests/*
+ - .zuul.d/*
+ - setup.py
+ - setup.cfg
+ - requirements.txt
+ - test-requirements.txt
+ required-projects:
+ - openstack/ara-server
+ run: playbooks/ara-server.yaml
+
+- job:
+ name: ara-server-role-integration-ubuntu
+ parent: ara-server-role-integration-base
+ nodeset: ubuntu-bionic
+
+- job:
+ name: ara-server-role-integration-fedora
+ parent: ara-server-role-integration-base
+ nodeset: fedora-latest
+
- project:
check:
jobs:
@@ -59,8 +87,12 @@
- ara-integration-fedora-devel:
voting: false
- ara-integration-ubuntu-2.6
+ - ara-server-role-integration-ubuntu
+ - ara-server-role-integration-fedora
gate:
jobs:
- ara-infra-website
- ara-integration-fedora-2.7
- ara-integration-ubuntu-2.6
+ - ara-server-role-integration-ubuntu
+ - ara-server-role-integration-fedora
diff --git a/playbooks/ara-server.yaml b/playbooks/ara-server.yaml
new file mode 100644
index 0000000..15aaa87
--- /dev/null
+++ b/playbooks/ara-server.yaml
@@ -0,0 +1,7 @@
+- name: Deploy ara-server
+ hosts: all
+ gather_facts: yes
+ vars:
+ ansible_python_interpreter: /usr/bin/python3
+ roles:
+ - ara_server
diff --git a/roles/ara_frontend_nginx/README.rst b/roles/ara_frontend_nginx/README.rst
new file mode 100644
index 0000000..cc7617f
--- /dev/null
+++ b/roles/ara_frontend_nginx/README.rst
@@ -0,0 +1,30 @@
+ansible-role-ara-frontend-nginx
+===============================
+
+Ansible role to install and configure nginx to serve instances of ara-server
+and ara-web.
+
+While this role can be used by itself, it is meant to be used alongside the
+Ansible roles for ara-server and ara-web.
+
+It is currently tested and supported against Ubuntu 18.04 and Fedora 29.
+
+Copyright
+=========
+
+::
+
+ Copyright (c) 2019 Red Hat, Inc.
+
+ ARA Records Ansible is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ ARA Records Ansible is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ARA Records Ansible. If not, see .
diff --git a/roles/ara_frontend_nginx/handlers/main.yaml b/roles/ara_frontend_nginx/handlers/main.yaml
new file mode 100644
index 0000000..b0b485a
--- /dev/null
+++ b/roles/ara_frontend_nginx/handlers/main.yaml
@@ -0,0 +1,24 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- name: restart nginx
+ become: true
+ service:
+ name: nginx
+ state: restarted
+ when: ara_nginx_enabled is not changed
diff --git a/roles/ara_frontend_nginx/meta/main.yaml b/roles/ara_frontend_nginx/meta/main.yaml
new file mode 100644
index 0000000..46b9a08
--- /dev/null
+++ b/roles/ara_frontend_nginx/meta/main.yaml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+galaxy_info:
+ author: David Moreau-Simard
+ description: Role to set up nginx for ara-server and ara-web
+ license: GPLv3
+ min_ansible_version: 2.7
+ platforms:
+ - name: Fedora
+ versions:
+ - 29
+ - name: Ubuntu
+ versions:
+ - bionic
+ galaxy_tags:
+ - ansible
+ - ara
+ - ara-server
+
+dependencies: []
diff --git a/roles/ara_frontend_nginx/tasks/main.yaml b/roles/ara_frontend_nginx/tasks/main.yaml
new file mode 100644
index 0000000..ddf4f43
--- /dev/null
+++ b/roles/ara_frontend_nginx/tasks/main.yaml
@@ -0,0 +1,65 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- name: Include OS family/distribution specific variables
+ include_vars: "{{ item }}"
+ with_first_found:
+ - "{{ ansible_distribution }}.yaml"
+ - "{{ ansible_os_family }}.yaml"
+
+- become: yes
+ block:
+ - name: Install nginx
+ package:
+ name: nginx
+ state: present
+
+ - name: Set selinux boolean to allow nginx to reverse proxy
+ seboolean:
+ name: httpd_can_network_connect
+ state: yes
+ persistent: yes
+ when: ansible_os_family == "RedHat"
+
+ - when:
+ - ara_server_frontend_fqdn is defined
+ - ara_server_wsgi_bind is defined
+ - ara_server_www_dir is defined
+ block:
+ - name: Set up the ara-server nginx vhost
+ template:
+ src: "{{ ara_nginx_server_vhost | default('ara-server.conf.j2') }}"
+ dest: "{{ ara_nginx_config_path }}/ara-server.conf"
+ notify:
+ - restart nginx
+
+ - name: Enable the nginx configuration on Debian-like systems
+ file:
+ src: "{{ ara_nginx_config_path }}/ara-server.conf"
+ dest: /etc/nginx/sites-enabled/ara-server.conf
+ state: link
+ when: ansible_os_family == 'Debian'
+ notify:
+ - restart nginx
+
+ - name: Enable and start nginx
+ service:
+ name: nginx
+ state: started
+ enabled: yes
+ register: ara_nginx_enabled
diff --git a/roles/ara_frontend_nginx/templates/ara-server.conf.j2 b/roles/ara_frontend_nginx/templates/ara-server.conf.j2
new file mode 100644
index 0000000..1f591d4
--- /dev/null
+++ b/roles/ara_frontend_nginx/templates/ara-server.conf.j2
@@ -0,0 +1,41 @@
+upstream ara_server {
+ # fail_timeout=0 means we always retry an upstream even if it failed
+ # to return a good HTTP response
+ server {{ ara_server_wsgi_bind }} fail_timeout=0;
+}
+
+server {
+ listen 80;
+ keepalive_timeout 5;
+ server_name {{ ara_server_frontend_fqdn }};
+
+ access_log /var/log/nginx/{{ ara_server_frontend_fqdn }}_access.log;
+ error_log /var/log/nginx/{{ ara_server_frontend_fqdn }}_error.log;
+
+ # /static contains files from "ara-manage collectstatic"
+ location /static {
+ alias {{ ara_server_www_dir }}/static;
+ expires 1;
+ access_log off;
+ add_header Cache-Control "public";
+ }
+
+ # There's nothing at /, redirect it to the actual API for convenience
+ location / {
+ return 301 http://{{ ara_server_frontend_fqdn }}/api/v1/;
+ }
+
+ location /api/v1/ {
+ # checks if the file exists, if not found proxy to app
+ try_files $uri @proxy_to_app;
+ }
+
+ location @proxy_to_app {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Host $http_host;
+
+ proxy_redirect off;
+ proxy_pass http://ara_server;
+ }
+}
diff --git a/roles/ara_frontend_nginx/vars/Fedora.yaml b/roles/ara_frontend_nginx/vars/Fedora.yaml
new file mode 100644
index 0000000..164743e
--- /dev/null
+++ b/roles/ara_frontend_nginx/vars/Fedora.yaml
@@ -0,0 +1,21 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+ara_nginx_user: nginx
+ara_nginx_group: nginx
+ara_nginx_config_path: /etc/nginx/conf.d
diff --git a/roles/ara_frontend_nginx/vars/Ubuntu.yaml b/roles/ara_frontend_nginx/vars/Ubuntu.yaml
new file mode 100644
index 0000000..6f0120e
--- /dev/null
+++ b/roles/ara_frontend_nginx/vars/Ubuntu.yaml
@@ -0,0 +1,21 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+ara_nginx_user: www-data
+ara_nginx_group: www-data
+ara_nginx_config_path: /etc/nginx/sites-available
diff --git a/roles/ara_server/README.rst b/roles/ara_server/README.rst
new file mode 100644
index 0000000..0d3f476
--- /dev/null
+++ b/roles/ara_server/README.rst
@@ -0,0 +1,73 @@
+ansible-role-ara-server
+=======================
+
+This Ansible role provides a framework for installing one or many instances of
+`ara-server `_ in a variety of
+opinionated deployment topologies.
+
+It is currently tested and supported against Ubuntu 18.04 and Fedora 29.
+
+Role Variables
+==============
+
+See ``defaults/main.yaml``.
+
+TL;DR
+=====
+
+This is what the role does by default out of the box:
+
+- Installs required packages
+- Creates a user for running ara-server
+- Creates standard directories (``/var/lib/ara``, ``/etc/ara``, ``/var/log/ara``, ``/var/www/ara-server``)
+- Retrieves ara-server from source
+- Installs ara-server in a virtualenv
+- Generates a random secret key if none are provided or already configured
+- Configures ``/etc/ara/settings.yaml``
+- Runs SQL migrations (``ara-manage migrate``)
+- Installs gunicorn in the same virtualenv as ara-server
+- Sets up a systemd unit file for running ara-server with gunicorn
+- Collects static files (``ara-manage collectstatic``) into ``/var/www/ara-server``
+- Includes the ``ara_frontend_nginx`` role to install and configure nginx as a reverse proxy to gunicorn
+
+About deployment topologies
+===========================
+
+This Ansible role is designed to support different opinionated topologies that
+can be selected with role variables.
+
+For example, the following role variables are used to provide the topology from
+the ``TL;DR`` above:
+
+- ``ara_server_install_method: source``
+- ``ara_server_wsgi_server: gunicorn``
+- ``ara_server_database_engine: django.db.backends.sqlite3``
+- ``ara_server_frontend_server: nginx``
+
+The intent is that as the role gains support for other install methods,
+wsgi servers, frontend servers or database engines, it will be possible to
+mix and match according to preference or requirements.
+
+Perhaps ara-server could be installed from pypi and run with uwsgi, nginx and mysql.
+Or maybe it could be installed from distribution packages and set up to run with apache, mod_wsgi and postgresql.
+Or any combination of any of those.
+
+Copyright
+=========
+
+::
+
+ Copyright (c) 2019 Red Hat, Inc.
+
+ ARA Records Ansible is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ ARA Records Ansible is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ARA Records Ansible. If not, see .
diff --git a/roles/ara_server/defaults/main.yaml b/roles/ara_server/defaults/main.yaml
new file mode 100644
index 0000000..f060513
--- /dev/null
+++ b/roles/ara_server/defaults/main.yaml
@@ -0,0 +1,171 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+####################################
+# ara-server installation settings
+####################################
+# User that runs the ara-server process and owns the files for the installation.
+ara_server_user: ara
+
+# Group for that user
+ara_server_group: ara
+
+# Root directories in which data, configuration and logs will be stored
+ara_server_home_dir: /var/lib/ara # git repos, virtualenvs, sqlite db
+ara_server_config_dir: /etc/ara # settings.yaml
+ara_server_log_dir: /var/log/ara # logs
+ara_server_www_dir: /var/www/ara-server # django collectstatic assets (html/css/js)
+
+# Whether or not ara-server should be installed in a virtual environment.
+# Running ara-server in a virtualenv is recommended to avoid conflicting with
+# system-wide python packages.
+ara_server_venv: true
+
+# Location where the virtualenv will be stored
+ara_server_venv_path: "{{ ara_server_home_dir }}/venv/ara-server"
+
+# How ara-server will be installed
+# source (default): installs from a local or remote git repository specified by ara_server_source
+# pypi (planned): installs from pypi
+ara_server_install_method: source
+
+# Version of ara-server to install
+# This can be a git ref (tag, branch, commit) when installing from source or
+# it can be a version number released to PyPi.
+# When using "latest" as the source version, HEAD will be used
+# When using "latest" as the pypi version, the latest release will be used
+ara_server_install_version: latest
+
+# The source where the git repository can be cloned from.
+# Can be an URL to a git repository or the path to a local repository on disk.
+ara_server_source: "https://git.openstack.org/openstack/ara-server"
+
+# Location where ara-server will be checked out when installing from source
+ara_server_source_checkout: "{{ ara_server_home_dir }}/git/ara-server"
+
+# The WSGI server for running ara-server's django application
+# - gunicorn (default)
+# - uwsgi (planned)
+# - mod_wsgi (planned)
+ara_server_wsgi_server: gunicorn
+
+# Address and port on which the wsgi server will bind
+ara_server_wsgi_bind: "127.0.0.1:8000"
+
+# The frontend server for serving the ara-server wsgi
+# - nginx (default)
+# - apache (planned)
+ara_server_frontend_server: nginx
+
+# The domain the frontend server will be listening on
+ara_server_frontend_fqdn: api.ara.example.org
+
+####################################
+# ara-server configuration settings
+# For more information, see documentation: https://ara-server.readthedocs.io/en/latest/configuring.html
+####################################
+
+# ARA_BASE_DIR - Default directory for storing data and configuration
+ara_server_base_dir: "{{ ara_server_home_dir }}/server"
+
+# ARA_SETTINGS - Path to an ara-server configuration file
+ara_server_settings: "{{ ara_server_config_dir }}/settings.yaml"
+
+# ARA_ENV - Environment to load configuration for
+ara_server_env: default
+
+# ARA_LOG_LEVEL - Log level of the different components
+ara_server_log_level: INFO
+
+# ARA_LOGGING - Python logging configuration
+ara_server_logging:
+ disable_existing_loggers: false
+ formatters:
+ normal:
+ format: '%(asctime)s %(levelname)s %(name)s: %(message)s'
+ handlers:
+ console:
+ class: logging.handlers.TimedRotatingFileHandler
+ formatter: normal
+ level: "{{ ara_server_log_level }}"
+ filename: "{{ ara_server_log_dir }}/server.log"
+ when: 'midnight'
+ interval: 1
+ backupCount: 30
+ loggers:
+ ara:
+ handlers:
+ - console
+ level: "{{ ara_server_log_level }}"
+ propagate: 0
+ root:
+ handlers:
+ - console
+ level: "{{ ara_server_log_level }}"
+ version: 1
+
+# ARA_CORS_ORIGIN_ALLOW_ALL - django-cors-headers’s CORS_ORIGIN_WHITELIST_ALLOW_ALL setting
+ara_server_cors_origin_allow_all: false
+
+# ARA_CORS_ORIGIN_WHITELIST - django-cors-headers’s CORS_ORIGIN_WHITELIST setting
+ara_server_cors_origin_whitelist:
+ - "127.0.0.1:8000"
+ - "localhost:3000"
+
+# ARA_SERVER_ALLOWED_HOSTS - Django’s ALLOWED_HOSTS setting
+ara_server_allowed_hosts:
+ - "127.0.0.1"
+ - "localhost"
+ - "::1"
+
+# ARA_DEBUG - Django's DEBUG setting
+ara_server_debug: false
+
+# ARA_SECRET_KEY - Django's SECRET_KEY setting
+# Note: If no key is provided, a random one will be generated once and persisted
+ara_server_secret_key: null
+
+# ARA_STATIC_ROOT - Django’s STATIC_ROOT setting
+ara_server_static_root: "{{ ara_server_www_dir }}/static"
+
+# ARA_STATIC_URL - Django's STATIC_URL setting
+ara_server_static_url: "/static/"
+
+# ARA_MEDIA_ROOT - Django's MEDIA_ROOT setting
+ara_server_media_root: "{{ ara_server_www_dir }}/media"
+
+# ARA_MEDIA_URL - Django's MEDIA_URL setting
+ara_server_media_url: "/media/"
+
+# ARA_DATABASE_ENGINE - Django’s ENGINE database setting
+ara_server_database_engine: django.db.backends.sqlite3
+
+# ARA_DATABASE_NAME - Django’s NAME database setting
+ara_server_database_name: "{{ ara_server_home_dir }}/server/ansible.sqlite"
+
+# ARA_DATABASE_USER - Django’s USER database setting
+ara_server_database_user: null
+
+# ARA_DATABASE_PASSWORD - Django’s PASSWORD database setting
+ara_server_database_password: null
+
+# ARA_DATABASE_HOST - Django’s HOST database setting
+ara_server_database_host: null
+
+# ARA_DATABASE_PORT - Django’s PORT database setting
+ara_server_database_port: null
diff --git a/roles/ara_server/files/ara-gunicorn.te b/roles/ara_server/files/ara-gunicorn.te
new file mode 100644
index 0000000..8fda81e
--- /dev/null
+++ b/roles/ara_server/files/ara-gunicorn.te
@@ -0,0 +1,14 @@
+module ara-gunicorn 1.0;
+
+require {
+ type var_lib_t;
+ type postgresql_db_t;
+ type init_t;
+ class file { execute execute_no_trans getattr open read };
+ class lnk_file { getattr read };
+}
+
+#============= init_t ==============
+allow init_t postgresql_db_t:file { getattr open read };
+allow init_t var_lib_t:file { execute execute_no_trans };
+allow init_t var_lib_t:lnk_file { getattr read };
diff --git a/roles/ara_server/handlers/main.yaml b/roles/ara_server/handlers/main.yaml
new file mode 100644
index 0000000..d15ffb8
--- /dev/null
+++ b/roles/ara_server/handlers/main.yaml
@@ -0,0 +1,30 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- name: restart ara-server
+ become: true
+ service:
+ name: ara-server
+ state: restarted
+ when: ara_server_service_enabled is not changed
+
+# Is there a better way ? Static files are not created with the httpd context
+- name: restore selinux context for static files
+ become: true
+ command: "restorecon -Rv {{ ara_server_www_dir }}"
+ when: ansible_os_family == "RedHat"
diff --git a/roles/ara_server/meta/main.yaml b/roles/ara_server/meta/main.yaml
new file mode 100644
index 0000000..fc8dbc1
--- /dev/null
+++ b/roles/ara_server/meta/main.yaml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+galaxy_info:
+ author: David Moreau-Simard
+ description: Role to set up ara-server
+ license: GPLv3
+ min_ansible_version: 2.7
+ platforms:
+ - name: Fedora
+ versions:
+ - 29
+ - name: Ubuntu
+ versions:
+ - bionic
+ galaxy_tags:
+ - ansible
+ - ara
+ - ara-server
+
+dependencies: []
diff --git a/roles/ara_server/tasks/config.yaml b/roles/ara_server/tasks/config.yaml
new file mode 100644
index 0000000..ef7b341
--- /dev/null
+++ b/roles/ara_server/tasks/config.yaml
@@ -0,0 +1,104 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- become: yes
+ become_user: "{{ ara_server_user }}"
+ block:
+ - name: Verify if a configuration file exists
+ stat:
+ path: "{{ ara_server_settings }}"
+ register: settings_stat
+
+ # If no secret key has been provided and this isn't the first time we are
+ # running, recover the secret key from the existing configuration file.
+ - when:
+ - ara_server_secret_key is none
+ - settings_stat.stat.exists
+ block:
+ - name: Read the configuration file
+ command: cat "{{ ara_server_settings }}"
+ changed_when: false
+ no_log: yes
+ register: settings_contents
+
+ - name: Recover existing secret key
+ vars:
+ config: "{{ settings_contents.stdout | from_yaml }}"
+ set_fact:
+ ara_server_secret_key: "{{ config[ara_server_env]['SECRET_KEY'] }}"
+ no_log: yes
+
+ # If no secret key has been provided and this is the first time we are
+ # running, generate a new random secret key that will be persisted in the
+ # configuration file.
+ - when:
+ - ara_server_secret_key is none
+ - not settings_stat.stat.exists
+ block:
+ - name: Generate a random secret key
+ environment:
+ PATH: "{{ path_with_virtualenv | default(omit) }}"
+ command: python3 -c "from django.utils.crypto import get_random_string; print(get_random_string(length=50))"
+ no_log: yes
+ register: generated_key
+
+ - name: Set ara_server_secret_key
+ set_fact:
+ ara_server_secret_key: "{{ generated_key.stdout }}"
+ no_log: yes
+
+ - name: Reconcile configuration
+ vars:
+ reconciled_configuration:
+ ALLOWED_HOSTS: "{{ ara_server_allowed_hosts }}"
+ BASE_DIR: "{{ ara_server_base_dir }}"
+ CORS_ORIGIN_ALLOW_ALL: "{{ ara_server_cors_origin_allow_all }}"
+ CORS_ORIGIN_WHITELIST: "{{ ara_server_cors_origin_whitelist }}"
+ DATABASES:
+ default:
+ ENGINE: "{{ ara_server_database_engine }}"
+ NAME: "{{ ara_server_database_name }}"
+ USER: "{{ ara_server_database_user }}"
+ PASSWORD: "{{ ara_server_database_password }}"
+ HOST: "{{ ara_server_database_host }}"
+ PORT: "{{ ara_server_database_port }}"
+ DEBUG: "{{ ara_server_debug }}"
+ LOGGING: "{{ ara_server_logging }}"
+ LOG_LEVEL: "{{ ara_server_log_level }}"
+ MEDIA_ROOT: "{{ ara_server_media_root }}"
+ MEDIA_URL: "{{ ara_server_media_url }}"
+ STATIC_ROOT: "{{ ara_server_static_root }}"
+ STATIC_URL: "{{ ara_server_static_url }}"
+ SECRET_KEY: "{{ ara_server_secret_key }}"
+ set_fact:
+ ara_server_configuration: "{'{{ ara_server_env }}': {{ reconciled_configuration }} }"
+
+- name: Configure ara-server
+ become: yes
+ copy:
+ content: |
+ ---
+ # Managed by the ara_server Ansible role
+ {{ ara_server_configuration | to_nice_yaml(indent=2) }}
+ dest: "{{ ara_server_settings }}"
+ owner: "{{ ara_server_user }}"
+ group: "{{ ara_server_group }}"
+ mode: 0750
+ notify:
+ - restart ara-server
+ no_log: yes
diff --git a/roles/ara_server/tasks/database_engine/django.db.backends.sqlite3.yaml b/roles/ara_server/tasks/database_engine/django.db.backends.sqlite3.yaml
new file mode 100644
index 0000000..8690b7b
--- /dev/null
+++ b/roles/ara_server/tasks/database_engine/django.db.backends.sqlite3.yaml
@@ -0,0 +1,34 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- become: yes
+ become_user: "{{ ara_server_user }}"
+ block:
+ - name: Ensure the database directory exists
+ file:
+ path: "{{ ara_server_database_name | dirname }}"
+ state: directory
+ owner: "{{ ara_server_user }}"
+ group: "{{ ara_server_group }}"
+ mode: 0750
+
+ - name: Run SQL migrations
+ environment:
+ ARA_SETTINGS: "{{ ara_server_settings }}"
+ PATH: "{{ path_with_virtualenv | default(omit) }}"
+ command: ara-manage migrate
diff --git a/roles/ara_server/tasks/install/source.yaml b/roles/ara_server/tasks/install/source.yaml
new file mode 100644
index 0000000..f2fc4d0
--- /dev/null
+++ b/roles/ara_server/tasks/install/source.yaml
@@ -0,0 +1,55 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+# Zuul takes care of preparing the source repository but we need to make it
+# available to the ara user.
+- when: zuul is defined
+ become: yes
+ block:
+ - name: Ensure git checkout directory exists
+ become_user: "{{ ara_server_user }}"
+ file:
+ path: "{{ ara_server_source_checkout | dirname }}"
+ state: directory
+
+ # Files will be owned by the Zuul user but allow for reading, we don't need
+ # to adjust permissions for this.
+ - name: Copy Zuul git repository for ara-server
+ command: "cp -r {{ ansible_user_dir }}/src/git.openstack.org/openstack/ara-server {{ ara_server_source_checkout }}"
+
+- become: yes
+ become_user: "{{ ara_server_user }}"
+ block:
+ - name: Prepare git repository for ara-server
+ git:
+ repo: "{{ ara_server_source }}"
+ dest: "{{ ara_server_source_checkout }}"
+ version: "{{ (ara_server_install_version == 'latest') | ternary('HEAD', ara_server_install_version) }}"
+ when: zuul is not defined
+
+ - name: Install ara-server
+ pip:
+ name: "{{ ara_server_source_checkout }}"
+ state: present
+ virtualenv: "{{ ara_server_venv | bool | ternary(ara_server_venv_path, omit) }}"
+ virtualenv_python: python3
+
+- name: Prefix the virtualenv bin directory to PATH
+ set_fact:
+ path_with_virtualenv: "{{ ara_server_venv_path }}/bin:{{ ansible_env.PATH }}"
+ when: ara_server_venv | bool
diff --git a/roles/ara_server/tasks/main.yaml b/roles/ara_server/tasks/main.yaml
new file mode 100644
index 0000000..f5b19ea
--- /dev/null
+++ b/roles/ara_server/tasks/main.yaml
@@ -0,0 +1,55 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- name: Set up pre-requirements
+ include_tasks: pre-requirements.yaml
+
+- name: Include ara-server installation
+ include_tasks: "install/{{ ara_server_install_method }}.yaml"
+
+- name: Include ara-server configuration
+ include_tasks: config.yaml
+
+- name: Include database engine configuration
+ include_tasks: "database_engine/{{ ara_server_database_engine }}.yaml"
+
+- name: Include backend server installation
+ include_tasks: "wsgi_server/{{ ara_server_wsgi_server }}.yaml"
+
+- name: Create web asset directory
+ become: yes
+ file:
+ path: "{{ ara_server_www_dir }}"
+ state: directory
+ owner: "{{ ara_server_user }}"
+ group: "{{ ara_server_group }}"
+ mode: 0755
+
+- name: Collect static files
+ become: yes
+ become_user: "{{ ara_server_user }}"
+ environment:
+ ARA_SETTINGS: "{{ ara_server_settings }}"
+ PATH: "{{ path_with_virtualenv | default(omit) }}"
+ command: ara-manage collectstatic --clear --no-input
+ notify:
+ - restore selinux context for static files
+
+- name: Include frontend server installation
+ include_role:
+ name: "ara_frontend_{{ ara_server_frontend_server }}"
diff --git a/roles/ara_server/tasks/pre-requirements.yaml b/roles/ara_server/tasks/pre-requirements.yaml
new file mode 100644
index 0000000..b38ae07
--- /dev/null
+++ b/roles/ara_server/tasks/pre-requirements.yaml
@@ -0,0 +1,63 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+# The ansible_python_version fact might end up retrieving the version of
+# python2 so we need to explicitely get the version of python 3 available.
+- name: Validate availability of Python 3.6
+ command: /usr/bin/python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))'
+ changed_when: false
+ failed_when: false
+ register: python_version
+
+- name: Fail pre-emptively if running Python <3.6
+ fail:
+ msg: "Python >=3.6 is required to run ara-server"
+ when: python_version.stdout is version('3.6', '<') or python_version.rc != 0
+
+- name: Include OS family/distribution specific variables
+ include_vars: "{{ item }}"
+ with_first_found:
+ - "{{ ansible_distribution }}.yaml"
+ - "{{ ansible_os_family }}.yaml"
+
+- become: true
+ block:
+ - name: Install required packages
+ package:
+ name: "{{ ara_server_required_packages }}"
+ state: present
+
+ - name: Create user for ara-server
+ user:
+ name: "{{ ara_server_user }}"
+ comment: User for ARA Records Ansible
+ shell: /sbin/nologin
+ home: "{{ ara_server_home_dir }}"
+
+ - name: Ensure required directories are created with the right permissions
+ file:
+ path: "{{ item }}"
+ state: directory
+ owner: "{{ ara_server_user }}"
+ group: "{{ ara_server_group }}"
+ mode: 0750
+ loop:
+ - "{{ ara_server_home_dir }}"
+ - "{{ ara_server_base_dir }}"
+ - "{{ ara_server_config_dir }}"
+ - "{{ ara_server_log_dir }}"
diff --git a/roles/ara_server/tasks/wsgi_server/gunicorn.yaml b/roles/ara_server/tasks/wsgi_server/gunicorn.yaml
new file mode 100644
index 0000000..53f3b68
--- /dev/null
+++ b/roles/ara_server/tasks/wsgi_server/gunicorn.yaml
@@ -0,0 +1,64 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+- become: yes
+ become_user: "{{ ara_server_user }}"
+ block:
+ - name: Install gunicorn
+ pip:
+ name: gunicorn
+ state: present
+ virtualenv: "{{ ara_server_venv | bool | ternary(ara_server_venv_path, omit) }}"
+ virtualenv_python: python3
+
+ - when: ansible_os_family == "RedHat"
+ block:
+ - name: Transfer gunicorn selinux type enforcement file
+ copy:
+ src: ara-gunicorn.te
+ dest: "{{ ara_server_home_dir }}/ara-gunicorn.te"
+
+ - name: Compile ara-gunicorn selinux module
+ command: "checkmodule -M -m -o {{ ara_server_home_dir }}/ara-gunicorn.mod {{ ara_server_home_dir }}/ara-gunicorn.te"
+
+ - name: Compile ara-gunicorn selinux policy package
+ command: "semodule_package -o {{ ara_server_home_dir }}/ara-gunicorn.pp -m {{ ara_server_home_dir }}/ara-gunicorn.mod"
+
+- become: yes
+ block:
+ - name: Install selinux policy package
+ command: "semodule -i {{ ara_server_home_dir }}/ara-gunicorn.pp"
+ when: ansible_os_family == "RedHat"
+
+ - name: Set up systemd unit file for gunicorn
+ template:
+ src: ara-server.service.j2
+ dest: /etc/systemd/system/ara-server.service
+ owner: root
+ group: root
+ mode: 0644
+ notify:
+ - restart ara-server
+
+ - name: Enable and start ara-server with gunicorn
+ service:
+ name: ara-server
+ state: started
+ enabled: yes
+ daemon_reload: yes
+ register: ara_server_service_enabled
diff --git a/roles/ara_server/templates/ara-server.service.j2 b/roles/ara_server/templates/ara-server.service.j2
new file mode 100644
index 0000000..a565b5e
--- /dev/null
+++ b/roles/ara_server/templates/ara-server.service.j2
@@ -0,0 +1,22 @@
+[Unit]
+Description=ARA Records Ansible API server with gunicorn
+After=network.target
+
+[Service]
+PIDFile=/run/ara-server/pid
+User={{ ara_server_user }}
+Group={{ ara_server_group }}
+RuntimeDirectory=ara-server
+WorkingDirectory={{ ara_server_home_dir }}
+Environment=ARA_SETTINGS={{ ara_server_settings }}
+{% if ara_server_venv %}
+ExecStart={{ ara_server_venv_path }}/bin/gunicorn --pid /run/ara-server/pid --workers=4 --bind {{ ara_server_wsgi_bind }} ara.server.wsgi
+{% else %}
+ExecStart=gunicorn --pid /run/ara-server/pid --workers=4 --bind {{ ara_server_wsgi_bind }} ara.server.wsgi
+{% endif %}
+ExecReload=/bin/kill -s HUP $MAINPID
+ExecStop=/bin/kill -s TERM $MAINPID
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/ara_server/vars/Fedora.yaml b/roles/ara_server/vars/Fedora.yaml
new file mode 100644
index 0000000..f6ac069
--- /dev/null
+++ b/roles/ara_server/vars/Fedora.yaml
@@ -0,0 +1,22 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+ara_server_required_packages:
+ - git
+ - libselinux-python
+ - policycoreutils-python-utils
diff --git a/roles/ara_server/vars/Ubuntu.yaml b/roles/ara_server/vars/Ubuntu.yaml
new file mode 100644
index 0000000..071046d
--- /dev/null
+++ b/roles/ara_server/vars/Ubuntu.yaml
@@ -0,0 +1,21 @@
+---
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of ARA Records Ansible.
+#
+# ARA Records Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARA Records Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ARA Records Ansible. If not, see .
+
+ara_server_required_packages:
+ - git
+ - python3-venv