This is an automated email from the ASF dual-hosted git repository. machristie pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/airavata.git
commit 096488938f62766098fc0dd0da0cc6b08a5edb54 Author: Marcus Christie <[email protected]> AuthorDate: Fri Aug 3 11:17:01 2018 -0400 AIRAVATA-2580 Ansible role for deploying Django portal Split out common httpd setup to a separate httpd role as well. --- dev-tools/ansible/django.yml | 35 ++++ .../scigap/develop/group_vars/django/vars.yml | 26 +++ .../scigap/develop/host_vars/seagrid/vars.yml | 45 +++++ .../scigap/develop/host_vars/seagrid/vault.yml | 12 ++ dev-tools/ansible/inventories/scigap/develop/hosts | 6 +- dev-tools/ansible/roles/django/defaults/main.yml | 69 +++++++ dev-tools/ansible/roles/django/handlers/main.yml | 33 ++++ dev-tools/ansible/roles/django/tasks/main.yml | 124 ++++++++++++ .../django/templates/django-ssl-vhost.conf.j2 | 72 +++++++ .../roles/django/templates/django-vhost.conf.j2 | 56 ++++++ .../roles/django/templates/settings_local.py.j2 | 93 +++++++++ .../ansible/roles/django_setup/tasks/main.yml | 48 +++++ dev-tools/ansible/roles/httpd/defaults/main.yml | 37 ++++ dev-tools/ansible/roles/httpd/handlers/main.yml | 26 +++ dev-tools/ansible/roles/httpd/tasks/main.yml | 81 ++++++++ .../ansible/roles/httpd/templates/default.conf.j2 | 5 + .../ansible/roles/httpd/templates/ssl.conf.j2 | 217 +++++++++++++++++++++ 17 files changed, 984 insertions(+), 1 deletion(-) diff --git a/dev-tools/ansible/django.yml b/dev-tools/ansible/django.yml new file mode 100644 index 0000000..295a546 --- /dev/null +++ b/dev-tools/ansible/django.yml @@ -0,0 +1,35 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- +# Run the following setup once +- hosts: django[0] + name: webserver setup + roles: + - env_setup + - httpd + +# Create a django virtual host +- hosts: django + name: Create/update Django portal for gateway + roles: + - django + +... diff --git a/dev-tools/ansible/inventories/scigap/develop/group_vars/django/vars.yml b/dev-tools/ansible/inventories/scigap/develop/group_vars/django/vars.yml new file mode 100644 index 0000000..c07f92f --- /dev/null +++ b/dev-tools/ansible/inventories/scigap/develop/group_vars/django/vars.yml @@ -0,0 +1,26 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- +user: "pga" +group: "pga" +gateway_data_store_hostname: "pgadev.scigap.org" +gateway_data_store_resource_id: "pgadev.scigap.org_7ddf28fd-d503-4ff8-bbc5-3279a7c3b99e" +gateway_data_store_ssh_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWgLve4J9WCohF/4UnbBZsh/nRkP1aM9FmA1FjKwK2gQAnKwhU+NrbsjW38h2Hi+8s9N2oZ9cCJHrvDi2U0cMxz4exIUBcVoRhw37ThlREHADeKR1FbKw0QLhTyfJb0K+1/8GWRluiFx0vHPptJe0KTqu+RJY0NSe+d/BEuGyCZ1hR+SKNuTgcb05Ia6opbSN5D68N9biseEux60d69ARQxLw+VN3Kr/UaBNpGIAfKLlLSUQlTyPA6G6UKCcJZv+/ye10oa0SK0qtrxMpL+4VJcVx+d56U7CUFWKEgPAaQrX1qdGUNDA7HKmD+EBtzw6DJqNJ0Cue/XuPe/RT62tpf" \ No newline at end of file diff --git a/dev-tools/ansible/inventories/scigap/develop/host_vars/seagrid/vars.yml b/dev-tools/ansible/inventories/scigap/develop/host_vars/seagrid/vars.yml new file mode 100644 index 0000000..e9dda47 --- /dev/null +++ b/dev-tools/ansible/inventories/scigap/develop/host_vars/seagrid/vars.yml @@ -0,0 +1,45 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- +doc_root_dir: "/var/www/portals/django-seagrid" +vhost_servername: "django.seagrid.org" +vhost_ssl: True +ssl_certificate_file: "/etc/letsencrypt/live/django.seagrid.org/cert.pem" +ssl_certificate_chain_file: "/etc/letsencrypt/live/django.seagrid.org/fullchain.pem" +ssl_certificate_key_file: "/etc/letsencrypt/live/django.seagrid.org/privkey.pem" + +## Keycloak related variables +tenant_domain: "seagrid" +oauth_client_key: "{{ vault_oauth_client_key }}" +oauth_client_secret: "{{ vault_oauth_client_secret }}" + +auth_options: + password: + name: "SEAGrid" + external: + - name: "CILogon" + idp_alias: "oidc" + +gateway_id: "seagrid" +# relative to document root dir +experiment_data_dir: "{{ user_data_dir }}/django-seagrid" + +... diff --git a/dev-tools/ansible/inventories/scigap/develop/host_vars/seagrid/vault.yml b/dev-tools/ansible/inventories/scigap/develop/host_vars/seagrid/vault.yml new file mode 100644 index 0000000..5eb9456 --- /dev/null +++ b/dev-tools/ansible/inventories/scigap/develop/host_vars/seagrid/vault.yml @@ -0,0 +1,12 @@ +$ANSIBLE_VAULT;1.1;AES256 +39306638393035653438346330346530306532373362653139623735396634623531316132376261 +3436356234663137326235386466393961376162366134380a303465306562373963376466393336 +66326531303039643734623936356538353061333438306565363037316263306136386661333665 +6264346234323361380a636533323831353865623837626539623039343936646330383362346231 +61306236303633633438383832663836333438333138373333316635666130323635343838323438 +61346136653531336136336435353331616539333834396634333038303763353438633233316338 +36343735396661376566356631356134653036663337336239653238656537623462613938366438 +31376363323831663734393737393331353865303164333936626662306536393936346662363863 +65336333373236303562646562656336393032613638353137393039633639363063303334643639 +62323263376639383136363234316632313963323730376531333235366238376232653864393938 +643238616561306532326237363561613734 diff --git a/dev-tools/ansible/inventories/scigap/develop/hosts b/dev-tools/ansible/inventories/scigap/develop/hosts index fd3a537..9ec0df1 100644 --- a/dev-tools/ansible/inventories/scigap/develop/hosts +++ b/dev-tools/ansible/inventories/scigap/develop/hosts @@ -1,5 +1,5 @@ --- -# inventory file : scigap production deployment +# inventory file : scigap develop deployment [zookeeper] 149.165.156.195 @@ -21,3 +21,7 @@ [keycloak] 149.165.156.151 + +[django] +seagrid ansible_host=pgadev.scigap.org +#simvascular ansible_host=pgadev.scigap.org \ No newline at end of file diff --git a/dev-tools/ansible/roles/django/defaults/main.yml b/dev-tools/ansible/roles/django/defaults/main.yml new file mode 100644 index 0000000..a5007bc --- /dev/null +++ b/dev-tools/ansible/roles/django/defaults/main.yml @@ -0,0 +1,69 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- +doc_root_dir: "/var/www/django-{{ gateway_id }}" +user_data_dir: "/var/www/user_data" +django_venv_dir: "{{ doc_root_dir }}/venv" +# real_user_data_dir is the same as user_data_dir but without symbolic links in it +real_user_data_dir: "{{ user_data_dir }}" +vhost_servername: "{{ groups['django'][0] }}" +vhost_ssl: False +httpd_confd_file_location: + RedHat: "/etc/httpd/conf.d/django-{{ gateway_id }}.conf" + Debian: "/etc/apache2/sites-available/django-{{ gateway_id }}.conf" +httpd_name: + Debian: apache2 + RedHat: httpd +httpd_log_dir: + Debian: /var/log/apache2 + RedHat: /var/log/httpd + +django_vhost_template: "django-vhost.conf.j2" +django_ssl_vhost_template: "django-ssl-vhost.conf.j2" +django_settings_local_template: "settings_local.py.j2" + +## Keycloak related variables +tenant_domain: "{{ gateway_id }}" +oauth_client_key: "RuLl_Uw7i_KXaLoAGJkiasTfyBYa" +oauth_client_secret: "vD9yi2ANkChzgWiih3RahrIcfsoa" +oauth_service_url: "{{ iam_server_url }}" +auth_options: + password: + name: "{{ portal_title }}" + # external: + # - name: "CILogon" + # idp_alias: "cilogon" +oauth_callback_url: "https://{{ vhost_servername }}/auth/callback" + + +## Airavata Client related variables +airavata_django_repo: "https://github.com/apache/airavata-django-portal.git" +airavata_django_git_branch: "master" +airavata_django_checkout: "{{ doc_root_dir}}/airavata-django-portal" +gateway_id: "{{ default_gateway }}" +# relative to document root dir +experiment_data_dir: "{{ user_data_dir }}" +gateway_data_store_resource_id: "js-170-103.jetstream-cloud.org_6497a464-3121-4b64-a7cb-d195b0a26c19" +gateway_data_store_hostname: "{{ groups['django'][0] }}" + +httpd_default_http_port: 80 +httpd_default_https_port: 443 +... diff --git a/dev-tools/ansible/roles/django/handlers/main.yml b/dev-tools/ansible/roles/django/handlers/main.yml new file mode 100644 index 0000000..808200f --- /dev/null +++ b/dev-tools/ansible/roles/django/handlers/main.yml @@ -0,0 +1,33 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- + +# Gracefully reload httpd +- name: restart httpd + service: name={{ httpd_name[ansible_os_family] }} state=reloaded enabled=yes + become: yes + +- name: restart uwsgi + file: + path: "{{ doc_root_dir }}/airavata-django-portal/django_airavata/wsgi.py" + state: touch + become: yes + become_user: "{{ user }}" diff --git a/dev-tools/ansible/roles/django/tasks/main.yml b/dev-tools/ansible/roles/django/tasks/main.yml new file mode 100644 index 0000000..e84d8ed --- /dev/null +++ b/dev-tools/ansible/roles/django/tasks/main.yml @@ -0,0 +1,124 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- +- name: Create root directory ({{ doc_root_dir }}) + file: path="{{ doc_root_dir }}" state=directory owner="{{user}}" group="{{group}}" + become: yes + +- name: Git clone django portal + git: + repo: "{{ airavata_django_repo }}" + dest: "{{ airavata_django_checkout }}" + version: "{{ airavata_django_git_branch }}" + update: yes + force: yes + become: yes + become_user: "{{user}}" + notify: + - restart uwsgi + +- name: Create virtual environment for Django portal and install dependencies + pip: + requirements: "{{ airavata_django_checkout }}/requirements.txt" + virtualenv: "{{ django_venv_dir }}" + virtualenv_command: "python3 -m venv" + become: yes + become_user: "{{user}}" + +- name: Copy the settings_local.py file + template: src={{ django_settings_local_template }} dest="{{ airavata_django_checkout }}/django_airavata/settings_local.py" owner="{{user}}" group="{{group}}" + become: yes + notify: + - restart uwsgi + +- name: Run Django's manage.py migrate + django_manage: + command: migrate + app_path: "{{ airavata_django_checkout }}" + virtualenv: "{{ django_venv_dir }}" + become: yes + become_user: "{{user}}" + +- name: Build JS + command: bash {{ airavata_django_checkout }}/build_js.sh + become: yes + become_user: "{{user}}" + +- name: Run Django's manage.py collectstatic + django_manage: + command: "collectstatic -i node_modules --noinput" + app_path: "{{ airavata_django_checkout }}" + virtualenv: "{{ django_venv_dir }}" + become: yes + become_user: "{{user}}" + +- name: Create experiment data dir {{ experiment_data_dir }} + file: path="{{ experiment_data_dir }}" state=directory owner="{{user}}" group="{{group}}" recurse=yes follow=yes + become: yes + +- name: set selinux context to allow read on static directory + sefcontext: + target: "{{ doc_root_dir }}/static(/.*)?" + setype: httpd_sys_content_t + state: present + become: yes + notify: + - restart httpd + when: ansible_os_family == "RedHat" + +- name: set selinux context to allow exec on virtual env directory + sefcontext: + target: "{{ django_venv_dir }}(/.*)?" + setype: httpd_sys_script_exec_t + state: present + become: yes + notify: + - restart httpd + when: ansible_os_family == "RedHat" + +- name: set selinux context to allow read/write on django directory + sefcontext: + target: "{{ airavata_django_checkout }}(/.*)?" + setype: httpd_sys_rw_content_t + state: present + become: yes + notify: + - restart httpd + when: ansible_os_family == "RedHat" + +- name: run restorecon on those directories + command: restorecon -F -R {{ doc_root_dir }} + become: yes + when: ansible_os_family == "RedHat" + +- name: copy virtual host config file + template: src={{ django_vhost_template }} dest={{ httpd_confd_file_location[ansible_os_family] }} backup=yes + become: yes + notify: + - restart httpd + when: not vhost_ssl + +- name: copy SSL enabled virtual host config file + template: src={{ django_ssl_vhost_template }} dest={{ httpd_confd_file_location[ansible_os_family] }} backup=yes + become: yes + notify: + - restart httpd + when: vhost_ssl \ No newline at end of file diff --git a/dev-tools/ansible/roles/django/templates/django-ssl-vhost.conf.j2 b/dev-tools/ansible/roles/django/templates/django-ssl-vhost.conf.j2 new file mode 100644 index 0000000..aa31c48 --- /dev/null +++ b/dev-tools/ansible/roles/django/templates/django-ssl-vhost.conf.j2 @@ -0,0 +1,72 @@ +{# +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#} + +{% if vhost_server_redirect is defined %} +<VirtualHost *:{{httpd_default_http_port}}> + ServerName {{ vhost_server_redirect }} + Redirect "/" "https://{{ vhost_servername }}" +</VirtualHost> +{% endif %} + +<VirtualHost *:{{ httpd_default_http_port }}> + ServerName {{ vhost_servername }} + + ## Redirect all http traffic to https + RewriteEngine On + RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} +</VirtualHost> + +<VirtualHost *:{{ httpd_default_https_port }}> + ServerName {{ vhost_servername }} + + Alias /robots.txt {{ doc_root_dir }}/static/robots.txt + Alias /favicon.ico {{ doc_root_dir }}/static/favicon.ico + + Alias /static/ {{ doc_root_dir }}/static/ + + <Directory {{ doc_root_dir }}/static> + Require all granted + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript + </Directory> + + WSGIDaemonProcess {{ vhost_servername }} display-name=%{GROUP} python-home={{ doc_root_dir }}/venv python-path={{ doc_root_dir }}/airavata-django-portal processes=2 user={{ user }} group={{ group }} + WSGIProcessGroup {{ vhost_servername }} + + WSGIScriptAlias / {{ doc_root_dir }}/airavata-django-portal/django_airavata/wsgi.py + + <Directory {{ doc_root_dir }}/airavata-django-portal/django_airavata> + <Files wsgi.py> + Require all granted + </Files> + </Directory> + + ErrorLog {{ httpd_log_dir[ansible_os_family] }}/django-{{ gateway_id }}.error.log + CustomLog {{ httpd_log_dir[ansible_os_family] }}/django-{{ gateway_id }}.requests.log combined + + SSLEngine on + # Disable SSLv3 which is vulnerable to the POODLE attack + SSLProtocol All -SSLv2 -SSLv3 + SSLCertificateFile {{ ssl_certificate_file }} + SSLCertificateChainFile {{ ssl_certificate_chain_file }} + SSLCertificateKeyFile {{ ssl_certificate_key_file }} +</VirtualHost> \ No newline at end of file diff --git a/dev-tools/ansible/roles/django/templates/django-vhost.conf.j2 b/dev-tools/ansible/roles/django/templates/django-vhost.conf.j2 new file mode 100644 index 0000000..90ebec8 --- /dev/null +++ b/dev-tools/ansible/roles/django/templates/django-vhost.conf.j2 @@ -0,0 +1,56 @@ +{# +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#} + +{% if vhost_server_redirect is defined %} +<VirtualHost *:{{httpd_default_http_port}}> + ServerName {{ vhost_server_redirect }} + Redirect "/" "http://{{ vhost_servername }}" +</VirtualHost> +{% endif %} + +<VirtualHost *:{{ httpd_default_http_port }}> + ServerName {{ vhost_servername }} + + Alias /robots.txt {{ doc_root_dir }}/static/robots.txt + Alias /favicon.ico {{ doc_root_dir }}/static/favicon.ico + + Alias /static/ {{ doc_root_dir }}/static/ + + <Directory {{ doc_root_dir }}/static> + Require all granted + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript + </Directory> + + WSGIDaemonProcess {{ vhost_servername }} display-name=%{GROUP} python-home={{ doc_root_dir }}/venv python-path={{ doc_root_dir }}/airavata-django-portal processes=2 user={{ user }} group={{ group }} + WSGIProcessGroup {{ vhost_servername }} + + WSGIScriptAlias / {{ doc_root_dir }}/airavata-django-portal/django_airavata/wsgi.py + + <Directory {{ doc_root_dir }}/airavata-django-portal/django_airavata> + <Files wsgi.py> + Require all granted + </Files> + </Directory> + + ErrorLog {{ httpd_log_dir[ansible_os_family] }}/django-{{ gateway_id }}.error.log + CustomLog {{ httpd_log_dir[ansible_os_family] }}/django-{{ gateway_id }}.requests.log combined +</VirtualHost> \ No newline at end of file diff --git a/dev-tools/ansible/roles/django/templates/settings_local.py.j2 b/dev-tools/ansible/roles/django/templates/settings_local.py.j2 new file mode 100644 index 0000000..c4e406d --- /dev/null +++ b/dev-tools/ansible/roles/django/templates/settings_local.py.j2 @@ -0,0 +1,93 @@ +{# +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#} + +""" +Override default Django settings for a particular instance. + +Copy this file to settings_local.py and modify as appropriate. This file will +be imported into settings.py last of all so settings in this file override any +defaults specified in settings.py. +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# Keycloak Configuration +KEYCLOAK_CLIENT_ID = '{{ oauth_client_key }}' +KEYCLOAK_CLIENT_SECRET = '{{ oauth_client_secret }}' +KEYCLOAK_AUTHORIZE_URL = '{{ oauth_service_url }}/realms/{{ tenant_domain }}/protocol/openid-connect/auth' +KEYCLOAK_TOKEN_URL = '{{ oauth_service_url }}/realms/{{ tenant_domain }}/protocol/openid-connect/token' +KEYCLOAK_USERINFO_URL = '{{ oauth_service_url }}/realms/{{ tenant_domain }}/protocol/openid-connect/userinfo' +KEYCLOAK_LOGOUT_URL = '{{ oauth_service_url }}/realms/{{ tenant_domain }}/protocol/openid-connect/logout' +KEYCLOAK_CA_CERTFILE = os.path.join(BASE_DIR, "django_airavata", "resources", "incommon_rsa_server_ca.pem") +KEYCLOAK_VERIFY_SSL = True + +AUTHENTICATION_OPTIONS = { + + {% if auth_options.password %} + 'password': { + 'name': '{{ auth_options.password.name }}' + }, + {% endif %} + {% if auth_options.external %} + 'external': [ + {% for external in auth_options.external %} + { + 'idp_alias': '{{ external.idp_alias }}', + 'name': '{{ external.name }}', + }, + {% endfor %} + ] + {% endif %} +} + +# Airavata API Configuration +GATEWAY_ID = '{{ gateway_id }}' +AIRAVATA_API_HOST = '{{ api_server_host }}' +{% if api_secured %} +AIRAVATA_API_PORT = {{ api_server_tls_port }} +AIRAVATA_API_SECURE = True +{% else %} +AIRAVATA_API_PORT = {{ api_server_port }} +AIRAVATA_API_SECURE = False +{% endif %} +GATEWAY_DATA_STORE_RESOURCE_ID = '{{ gateway_data_store_resource_id }}' +GATEWAY_DATA_STORE_DIR = '{{ experiment_data_dir }}' +GATEWAY_DATA_STORE_HOSTNAME = '{{ gateway_data_store_hostname }}' + +# Profile Service Configuration +PROFILE_SERVICE_HOST = '{{ profile_service_host }}' +PROFILE_SERVICE_PORT = {{ profile_service_port }} +PROFILE_SERVICE_SECURE = False + +# Sharing API Configuration +SHARING_API_HOST = '{{ sharing_registry_host }}' +SHARING_API_PORT = {{ sharing_registry_port }} +SHARING_API_SECURE = False + +STATIC_ROOT = "{{ doc_root_dir }}/static/" +FILE_UPLOAD_TEMP_DIR = "{{ experiment_data_dir }}/tmp/" + +ALLOWED_HOSTS = ['{{ vhost_servername }}'] + diff --git a/dev-tools/ansible/roles/django_setup/tasks/main.yml b/dev-tools/ansible/roles/django_setup/tasks/main.yml new file mode 100644 index 0000000..af9c2b5 --- /dev/null +++ b/dev-tools/ansible/roles/django_setup/tasks/main.yml @@ -0,0 +1,48 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +--- +# TODO: install python34 +# sudo yum -y install python34 +# sudo yum -y install httpd-devel +# sudo yum -y install python34-devel + +# TODO: fetch and build mod_wsgi +# mkdir mod_wsgi +# cd mod_wsgi/ +# curl -LO https://github.com/GrahamDumpleton/mod_wsgi/archive/4.5.17.tar.gz +# tar zxf 4.5.17.tar.gz +# cd mod_wsgi-4.5.17/ +# ./configure --with-python=/usr/bin/python3 +# make +# sudo make install + +# TODO: configure apache to load mod_wsgi +# * configure Apache to load mod_wsgi +# ``` +# sudo vim /etc/httpd/conf.modules.d/00-wsgi.conf +# ``` +# * 00-wsgi.conf file contains +# ``` +# LoadModule wsgi_module modules/mod_wsgi.so +# ``` + +# TODO: install Node.js EPEL repository and then install nodejs +# sudo curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - +# sudo yum install nodejs \ No newline at end of file diff --git a/dev-tools/ansible/roles/httpd/defaults/main.yml b/dev-tools/ansible/roles/httpd/defaults/main.yml new file mode 100644 index 0000000..77b94ad --- /dev/null +++ b/dev-tools/ansible/roles/httpd/defaults/main.yml @@ -0,0 +1,37 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- +httpd_default_conf_file_location: + RedHat: "/etc/httpd/conf.d/default.conf" + Debian: "/etc/apache2/sites-available/default.conf" +httpd_ssl_conf_file_location: + RedHat: "/etc/httpd/conf.d/ssl.conf" + # TODO: Debian file layout is different, so we really need a different ssl.conf for Debian + Debian: "/etc/apache2/mods-available/ssl.conf" + +httpd_default_conf_template: "default.conf.j2" +httpd_ssl_conf_template: "ssl.conf.j2" + +gateway_data_store_ssh_public_key: "" + +httpd_default_http_port: 80 +httpd_default_https_port: 443 +... diff --git a/dev-tools/ansible/roles/httpd/handlers/main.yml b/dev-tools/ansible/roles/httpd/handlers/main.yml new file mode 100644 index 0000000..af37327 --- /dev/null +++ b/dev-tools/ansible/roles/httpd/handlers/main.yml @@ -0,0 +1,26 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +--- + +# Gracefully reload httpd +- name: restart httpd + service: name={{ httpd_name[ansible_os_family] }} state=reloaded enabled=yes + become: yes \ No newline at end of file diff --git a/dev-tools/ansible/roles/httpd/tasks/main.yml b/dev-tools/ansible/roles/httpd/tasks/main.yml new file mode 100644 index 0000000..469c105 --- /dev/null +++ b/dev-tools/ansible/roles/httpd/tasks/main.yml @@ -0,0 +1,81 @@ + +# SELinux configuration +- name: set selinux to enforcing + selinux: state=enforcing policy=targeted + become: yes + when: ansible_os_family == "RedHat" + +- name: allow httpd to connect out to the network + seboolean: + name: httpd_can_network_connect + state: yes + persistent: yes + become: yes + notify: + - restart httpd + when: ansible_os_family == "RedHat" + +- name: copy default virtual host file + template: src={{ httpd_default_conf_template }} dest={{ httpd_default_conf_file_location[ansible_os_family] }} backup=yes + become: yes + notify: + - restart httpd + +- name: copy modified ssl.conf file + template: src={{ httpd_ssl_conf_template }} dest={{ httpd_ssl_conf_file_location[ansible_os_family] }} backup=yes + become: yes + notify: + - restart httpd + # TODO: make the same fix (disabling SSLv3) on Debian systems too + when: ansible_os_family == "RedHat" + +# Gateway user data directory and SSH key +- name: Create user data dir {{ real_user_data_dir }} + file: path="{{ real_user_data_dir }}" state=directory owner="{{user}}" group="{{group}}" + become: yes + +- name: Symlink user data dir {{ user_data_dir }} to {{ real_user_data_dir }} + file: src="{{ real_user_data_dir }}" dest="{{ user_data_dir }}" state=link owner="{{user}}" group="{{group}}" + become: yes + when: user_data_dir != real_user_data_dir + +- name: set selinux context to allow read/write on the user data directory + sefcontext: + # For SELinux file contexts, the real path without symbolic links must be used + target: "{{ real_user_data_dir }}(/.*)?" + setype: httpd_sys_rw_content_t + state: present + become: yes + notify: + - restart httpd + when: ansible_os_family == "RedHat" + +- name: run restorecon on user data directory + command: restorecon -F -R {{ user_data_dir }} + become: yes + when: ansible_os_family == "RedHat" + +- name: copy pga user's SSH key for the gateway data store + authorized_key: + user: "{{user}}" + key: "{{ gateway_data_store_ssh_public_key }}" + become: yes + when: gateway_data_store_ssh_public_key != "" + +# Firewall settings +- name: Enable https and http service on public zone + firewalld: service="{{ item }}" permanent=true state=enabled zone=public immediate=True + with_items: + - http + - https + become: yes + +- name: open firewall port {{ httpd_default_http_port }} + firewalld: port="{{ httpd_default_http_port }}/tcp" + zone=public permanent=true state=enabled immediate=yes + become: yes + +- name: open firewall port {{ httpd_default_https_port }} + firewalld: port="{{ httpd_default_https_port }}/tcp" + zone=public permanent=true state=enabled immediate=yes + become: yes diff --git a/dev-tools/ansible/roles/httpd/templates/default.conf.j2 b/dev-tools/ansible/roles/httpd/templates/default.conf.j2 new file mode 100644 index 0000000..6791fb0 --- /dev/null +++ b/dev-tools/ansible/roles/httpd/templates/default.conf.j2 @@ -0,0 +1,5 @@ +# Setup default virtual host as a catchall to prevent resolving to the first defined virtual host +# This will show the welcome page when requesting on the ip address or server default hostname +<VirtualHost _default_:{{ httpd_default_http_port }}> + DocumentRoot "/www/default" +</VirtualHost> diff --git a/dev-tools/ansible/roles/httpd/templates/ssl.conf.j2 b/dev-tools/ansible/roles/httpd/templates/ssl.conf.j2 new file mode 100644 index 0000000..5617203 --- /dev/null +++ b/dev-tools/ansible/roles/httpd/templates/ssl.conf.j2 @@ -0,0 +1,217 @@ +# +# When we also provide SSL we have to listen to the +# the HTTPS port in addition. +# +Listen {{ httpd_default_https_port }} https + +## +## SSL Global Context +## +## All SSL configuration in this context applies both to +## the main server and all SSL-enabled virtual hosts. +## + +# Pass Phrase Dialog: +# Configure the pass phrase gathering process. +# The filtering dialog program (`builtin' is a internal +# terminal dialog) has to provide the pass phrase on stdout. +SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog + +# Inter-Process Session Cache: +# Configure the SSL Session Cache: First the mechanism +# to use and second the expiring timeout (in seconds). +SSLSessionCache shmcb:/run/httpd/sslcache(512000) +SSLSessionCacheTimeout 300 + +# Pseudo Random Number Generator (PRNG): +# Configure one or more sources to seed the PRNG of the +# SSL library. The seed data should be of good random quality. +# WARNING! On some platforms /dev/random blocks if not enough entropy +# is available. This means you then cannot use the /dev/random device +# because it would lead to very long connection times (as long as +# it requires to make more entropy available). But usually those +# platforms additionally provide a /dev/urandom device which doesn't +# block. So, if available, use this one instead. Read the mod_ssl User +# Manual for more details. +SSLRandomSeed startup file:/dev/urandom 256 +SSLRandomSeed connect builtin +#SSLRandomSeed startup file:/dev/random 512 +#SSLRandomSeed connect file:/dev/random 512 +#SSLRandomSeed connect file:/dev/urandom 512 + +# +# Use "SSLCryptoDevice" to enable any supported hardware +# accelerators. Use "openssl engine -v" to list supported +# engine names. NOTE: If you enable an accelerator and the +# server does not start, consult the error logs and ensure +# your accelerator is functioning properly. +# +SSLCryptoDevice builtin +#SSLCryptoDevice ubsec + +## +## SSL Virtual Host Context +## + +<VirtualHost _default_:{{ httpd_default_https_port }}> + +# General setup for the virtual host, inherited from global configuration +#DocumentRoot "/var/www/html" +#ServerName www.example.com:443 + +# Use separate log files for the SSL virtual host; note that LogLevel +# is not inherited from httpd.conf. +ErrorLog logs/ssl_error_log +TransferLog logs/ssl_access_log +LogLevel warn + +# SSL Engine Switch: +# Enable/Disable SSL for this virtual host. +SSLEngine on + +# SSL Protocol support: +# List the enable protocol levels with which clients will be able to +# connect. Disable SSLv2 access by default: +# Disable SSLv3 which is vulnerable to the POODLE attack +SSLProtocol All -SSLv2 -SSLv3 + +# SSL Cipher Suite: +# List the ciphers that the client is permitted to negotiate. +# See the mod_ssl documentation for a complete list. +SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA + +# Speed-optimized SSL Cipher configuration: +# If speed is your main concern (on busy HTTPS servers e.g.), +# you might want to force clients to specific, performance +# optimized ciphers. In this case, prepend those ciphers +# to the SSLCipherSuite list, and enable SSLHonorCipherOrder. +# Caveat: by giving precedence to RC4-SHA and AES128-SHA +# (as in the example below), most connections will no longer +# have perfect forward secrecy - if the server's key is +# compromised, captures of past or future traffic must be +# considered compromised, too. +#SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5 +#SSLHonorCipherOrder on + +# Server Certificate: +# Point SSLCertificateFile at a PEM encoded certificate. If +# the certificate is encrypted, then you will be prompted for a +# pass phrase. Note that a kill -HUP will prompt again. A new +# certificate can be generated using the genkey(1) command. +SSLCertificateFile /etc/pki/tls/certs/localhost.crt + +# Server Private Key: +# If the key is not combined with the certificate, use this +# directive to point at the key file. Keep in mind that if +# you've both a RSA and a DSA private key you can configure +# both in parallel (to also allow the use of DSA ciphers, etc.) +SSLCertificateKeyFile /etc/pki/tls/private/localhost.key + +# Server Certificate Chain: +# Point SSLCertificateChainFile at a file containing the +# concatenation of PEM encoded CA certificates which form the +# certificate chain for the server certificate. Alternatively +# the referenced file can be the same as SSLCertificateFile +# when the CA certificates are directly appended to the server +# certificate for convinience. +#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt + +# Certificate Authority (CA): +# Set the CA certificate verification path where to find CA +# certificates for client authentication or alternatively one +# huge file containing all of them (file must be PEM encoded) +#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt + +# Client Authentication (Type): +# Client certificate verification type and depth. Types are +# none, optional, require and optional_no_ca. Depth is a +# number which specifies how deeply to verify the certificate +# issuer chain before deciding the certificate is not valid. +#SSLVerifyClient require +#SSLVerifyDepth 10 + +# Access Control: +# With SSLRequire you can do per-directory access control based +# on arbitrary complex boolean expressions containing server +# variable checks and other lookup directives. The syntax is a +# mixture between C and Perl. See the mod_ssl documentation +# for more details. +#<Location /> +#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \ +# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ +# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \ +# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \ +# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \ +# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +#</Location> + +# SSL Engine Options: +# Set various options for the SSL engine. +# o FakeBasicAuth: +# Translate the client X.509 into a Basic Authorisation. This means that +# the standard Auth/DBMAuth methods can be used for access control. The +# user name is the `one line' version of the client's X.509 certificate. +# Note that no password is obtained from the user. Every entry in the user +# file needs this password: `xxj31ZMTZzkVA'. +# o ExportCertData: +# This exports two additional environment variables: SSL_CLIENT_CERT and +# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the +# server (always existing) and the client (only existing when client +# authentication is used). This can be used to import the certificates +# into CGI scripts. +# o StdEnvVars: +# This exports the standard SSL/TLS related `SSL_*' environment variables. +# Per default this exportation is switched off for performance reasons, +# because the extraction step is an expensive operation and is usually +# useless for serving static content. So one usually enables the +# exportation for CGI and SSI requests only. +# o StrictRequire: +# This denies access when "SSLRequireSSL" or "SSLRequire" applied even +# under a "Satisfy any" situation, i.e. when it applies access is denied +# and no other module can change it. +# o OptRenegotiate: +# This enables optimized SSL connection renegotiation handling when SSL +# directives are used in per-directory context. +#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire +<Files ~ "\.(cgi|shtml|phtml|php3?)$"> + SSLOptions +StdEnvVars +</Files> +<Directory "/var/www/cgi-bin"> + SSLOptions +StdEnvVars +</Directory> + +# SSL Protocol Adjustments: +# The safe and default but still SSL/TLS standard compliant shutdown +# approach is that mod_ssl sends the close notify alert but doesn't wait for +# the close notify alert from client. When you need a different shutdown +# approach you can use one of the following variables: +# o ssl-unclean-shutdown: +# This forces an unclean shutdown when the connection is closed, i.e. no +# SSL close notify alert is send or allowed to received. This violates +# the SSL/TLS standard but is needed for some brain-dead browsers. Use +# this when you receive I/O errors because of the standard approach where +# mod_ssl sends the close notify alert. +# o ssl-accurate-shutdown: +# This forces an accurate shutdown when the connection is closed, i.e. a +# SSL close notify alert is send and mod_ssl waits for the close notify +# alert of the client. This is 100% SSL/TLS standard compliant, but in +# practice often causes hanging connections with brain-dead browsers. Use +# this only for browsers where you know that their SSL implementation +# works correctly. +# Notice: Most problems of broken clients are also related to the HTTP +# keep-alive facility, so you usually additionally want to disable +# keep-alive for those clients, too. Use variable "nokeepalive" for this. +# Similarly, one has to force some clients to use HTTP/1.0 to workaround +# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and +# "force-response-1.0" for this. +BrowserMatch "MSIE [2-5]" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + +# Per-Server Logging: +# The home of a custom SSL log file. Use this when you want a +# compact non-error SSL logfile on a virtual host basis. +CustomLog logs/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + +</VirtualHost>
