From b6ad0dd06818f854dfb6ba5b702f85f70d8a8167 Mon Sep 17 00:00:00 2001 From: Drew Larson Date: Wed, 23 Mar 2016 16:29:28 -0600 Subject: [PATCH] Initial commit. --- .gitignore | 7 + README.md | 33 + Vagrantfile | 53 ++ bikeshop_project/.coveragerc | 7 + bikeshop_project/bikeshop/__init__.py | 0 .../bikeshop/settings/__init__.py | 0 bikeshop_project/bikeshop/settings/base.py | 117 ++++ .../bikeshop/settings/development.py | 47 ++ bikeshop_project/bikeshop/urls.py | 21 + bikeshop_project/bikeshop/wsgi.py | 16 + bikeshop_project/core/__init__.py | 0 bikeshop_project/core/admin.py | 3 + bikeshop_project/core/apps.py | 5 + .../core/migrations/0001_initial.py | 35 + .../core/migrations/0002_payment.py | 25 + .../core/migrations/0003_visit.py | 27 + bikeshop_project/core/migrations/__init__.py | 0 bikeshop_project/core/models.py | 49 ++ bikeshop_project/core/tests.py | 3 + bikeshop_project/core/views.py | 3 + bikeshop_project/manage.py | 10 + bikeshop_project/registration/__init__.py | 0 bikeshop_project/registration/admin.py | 3 + bikeshop_project/registration/apps.py | 5 + .../registration/migrations/0001_initial.py | 49 ++ .../registration/migrations/__init__.py | 0 bikeshop_project/registration/models.py | 87 +++ bikeshop_project/registration/tests.py | 3 + bikeshop_project/registration/views.py | 3 + package.json | 11 + provision/group_vars/all | 14 + .../group_vars/production/non-secrets.yml | 11 + provision/group_vars/production/secrets.yml | 10 + provision/group_vars/staging/non-secrets.yml | 10 + provision/group_vars/staging/secrets.yml | 2 + provision/inventories/production | 5 + provision/roles/app/tasks/main.yml | 3 + provision/roles/app/tasks/prepare.yml | 5 + provision/roles/app/tasks/virtualenv.yml | 15 + provision/roles/app/templates/sparse-checkout | 2 + provision/roles/common/tasks/main.yml | 22 + provision/roles/database/tasks/main.yml | 18 + provision/roles/deploy-code/tasks/main.yml | 36 ++ provision/roles/django/tasks/main.yml | 14 + provision/roles/handlers/main.yml | 3 + provision/roles/nginx/handlers/main.yml | 2 + provision/roles/nginx/tasks/main.yml | 12 + .../templates/production/nginx-site.conf | 61 ++ .../nginx/templates/staging/nginx-site.conf | 31 + provision/roles/python/tasks/main.yml | 14 + provision/roles/supervisor/handlers/main.yml | 3 + provision/roles/supervisor/tasks/main.yml | 12 + .../roles/supervisor/tasks/staging/main.yml | 4 + .../production/supervisor-program.conf | 45 ++ .../templates/staging/supervisor-program.conf | 10 + provision/roles/tasks/main.yml | 4 + provision/roles/tasks/staging/main.yml | 4 + .../production/supervisor-program.conf | 11 + .../templates/staging/supervisor-program.conf | 10 + .../roles/zenoamaro.postgresql/.gitignore | 1 + .../roles/zenoamaro.postgresql/.travis.yml | 28 + .../roles/zenoamaro.postgresql/LICENSE.md | 21 + .../roles/zenoamaro.postgresql/README.md | 117 ++++ .../roles/zenoamaro.postgresql/Vagrantfile | 62 ++ .../roles/zenoamaro.postgresql/boxed.yml | 26 + .../zenoamaro.postgresql/defaults/main.yml | 606 ++++++++++++++++++ .../zenoamaro.postgresql/handlers/main.yml | 8 + .../roles/zenoamaro.postgresql/inventory | 19 + provision/roles/zenoamaro.postgresql/main.yml | 19 + .../meta/.galaxy_install_info | 1 + .../roles/zenoamaro.postgresql/meta/main.yml | 21 + .../zenoamaro.postgresql/tasks/configure.yml | 55 ++ .../zenoamaro.postgresql/tasks/extensions.yml | 49 ++ .../zenoamaro.postgresql/tasks/install.yml | 51 ++ .../roles/zenoamaro.postgresql/tasks/main.yml | 5 + .../templates/environment | 11 + .../templates/pg_ctl.conf | 5 + .../templates/pg_hba.conf | 112 ++++ .../templates/pg_ident.conf | 46 ++ .../templates/postgresql.conf | 530 +++++++++++++++ provision/roles/zenoamaro.postgresql/test.yml | 24 + provision/site.retry | 1 + provision/site.yml | 18 + provision/templates/humans.txt | 18 + provision/templates/pg_hba.conf | 3 + requirements/base.txt | 8 + requirements/development.txt | 4 + requirements/production.txt | 2 + requirements/staging.txt | 1 + requirements/testing.txt | 2 + 90 files changed, 2889 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 Vagrantfile create mode 100644 bikeshop_project/.coveragerc create mode 100644 bikeshop_project/bikeshop/__init__.py create mode 100644 bikeshop_project/bikeshop/settings/__init__.py create mode 100644 bikeshop_project/bikeshop/settings/base.py create mode 100644 bikeshop_project/bikeshop/settings/development.py create mode 100644 bikeshop_project/bikeshop/urls.py create mode 100644 bikeshop_project/bikeshop/wsgi.py create mode 100644 bikeshop_project/core/__init__.py create mode 100644 bikeshop_project/core/admin.py create mode 100644 bikeshop_project/core/apps.py create mode 100644 bikeshop_project/core/migrations/0001_initial.py create mode 100644 bikeshop_project/core/migrations/0002_payment.py create mode 100644 bikeshop_project/core/migrations/0003_visit.py create mode 100644 bikeshop_project/core/migrations/__init__.py create mode 100644 bikeshop_project/core/models.py create mode 100644 bikeshop_project/core/tests.py create mode 100644 bikeshop_project/core/views.py create mode 100755 bikeshop_project/manage.py create mode 100644 bikeshop_project/registration/__init__.py create mode 100644 bikeshop_project/registration/admin.py create mode 100644 bikeshop_project/registration/apps.py create mode 100644 bikeshop_project/registration/migrations/0001_initial.py create mode 100644 bikeshop_project/registration/migrations/__init__.py create mode 100644 bikeshop_project/registration/models.py create mode 100644 bikeshop_project/registration/tests.py create mode 100644 bikeshop_project/registration/views.py create mode 100644 package.json create mode 100644 provision/group_vars/all create mode 100644 provision/group_vars/production/non-secrets.yml create mode 100644 provision/group_vars/production/secrets.yml create mode 100644 provision/group_vars/staging/non-secrets.yml create mode 100644 provision/group_vars/staging/secrets.yml create mode 100644 provision/inventories/production create mode 100644 provision/roles/app/tasks/main.yml create mode 100644 provision/roles/app/tasks/prepare.yml create mode 100644 provision/roles/app/tasks/virtualenv.yml create mode 100644 provision/roles/app/templates/sparse-checkout create mode 100644 provision/roles/common/tasks/main.yml create mode 100644 provision/roles/database/tasks/main.yml create mode 100644 provision/roles/deploy-code/tasks/main.yml create mode 100644 provision/roles/django/tasks/main.yml create mode 100644 provision/roles/handlers/main.yml create mode 100644 provision/roles/nginx/handlers/main.yml create mode 100644 provision/roles/nginx/tasks/main.yml create mode 100644 provision/roles/nginx/templates/production/nginx-site.conf create mode 100644 provision/roles/nginx/templates/staging/nginx-site.conf create mode 100644 provision/roles/python/tasks/main.yml create mode 100644 provision/roles/supervisor/handlers/main.yml create mode 100644 provision/roles/supervisor/tasks/main.yml create mode 100644 provision/roles/supervisor/tasks/staging/main.yml create mode 100644 provision/roles/supervisor/templates/production/supervisor-program.conf create mode 100644 provision/roles/supervisor/templates/staging/supervisor-program.conf create mode 100644 provision/roles/tasks/main.yml create mode 100644 provision/roles/tasks/staging/main.yml create mode 100644 provision/roles/templates/production/supervisor-program.conf create mode 100644 provision/roles/templates/staging/supervisor-program.conf create mode 100644 provision/roles/zenoamaro.postgresql/.gitignore create mode 100644 provision/roles/zenoamaro.postgresql/.travis.yml create mode 100644 provision/roles/zenoamaro.postgresql/LICENSE.md create mode 100644 provision/roles/zenoamaro.postgresql/README.md create mode 100644 provision/roles/zenoamaro.postgresql/Vagrantfile create mode 100644 provision/roles/zenoamaro.postgresql/boxed.yml create mode 100644 provision/roles/zenoamaro.postgresql/defaults/main.yml create mode 100644 provision/roles/zenoamaro.postgresql/handlers/main.yml create mode 100644 provision/roles/zenoamaro.postgresql/inventory create mode 100644 provision/roles/zenoamaro.postgresql/main.yml create mode 100644 provision/roles/zenoamaro.postgresql/meta/.galaxy_install_info create mode 100644 provision/roles/zenoamaro.postgresql/meta/main.yml create mode 100644 provision/roles/zenoamaro.postgresql/tasks/configure.yml create mode 100644 provision/roles/zenoamaro.postgresql/tasks/extensions.yml create mode 100644 provision/roles/zenoamaro.postgresql/tasks/install.yml create mode 100644 provision/roles/zenoamaro.postgresql/tasks/main.yml create mode 100644 provision/roles/zenoamaro.postgresql/templates/environment create mode 100644 provision/roles/zenoamaro.postgresql/templates/pg_ctl.conf create mode 100644 provision/roles/zenoamaro.postgresql/templates/pg_hba.conf create mode 100644 provision/roles/zenoamaro.postgresql/templates/pg_ident.conf create mode 100644 provision/roles/zenoamaro.postgresql/templates/postgresql.conf create mode 100644 provision/roles/zenoamaro.postgresql/test.yml create mode 100644 provision/site.retry create mode 100644 provision/site.yml create mode 100755 provision/templates/humans.txt create mode 100644 provision/templates/pg_hba.conf create mode 100644 requirements/base.txt create mode 100644 requirements/development.txt create mode 100644 requirements/production.txt create mode 100644 requirements/staging.txt create mode 100644 requirements/testing.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b6c371 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.vagrant +.idea +*.pyc +trailersafeguard_project/db.sqlite3 +trailersafeguard_project/static +trailersafeguard_project/celerybeat.pid diff --git a/README.md b/README.md new file mode 100644 index 0000000..56f467d --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +## Quickstart +Maybe this isn't such a quick start, but it's the best I have right now. After the following steps are completed, you will have a working development version of the Trailer-Safeguard Django application connectable on [bikeshop-dev.local:8000/](http://bikeshop-dev.local:8000/). + +1. Make sure Virtualbox is installed and updated +2. Make sure Vagrant is installed and updated +3. Verify *pip* is installed `which pip` +4. Verify *ansible* is installed `which ansible` +5. Clone source `git clone AHHHHHH` +6. `ansible-galaxy install zenoamaro.postgresql -p provision/roles` +7. `vagrant plugin install vagrant-hostsupdater` +8. `vagrant up` +9. `vagrant ssh` +10. `cd /srv/bikeshop && . /opt/venv/bikeshop_development/bin/activate` +11. `./manage.py migrate` +12. `./manage.py loaddata core/migrations/initial_data.yaml && ./manage.py loaddata authentication/migrations/initial_data.yaml` +13. `./manage.py runserver 0.0.0.0:8000` + +### Example of dumpdata command +./manage.py dumpdata --exclude=auth --exclude=contenttypes --exclude=incoming --format=yaml + +### Reset the Postgres DB +1. `vagrant ssh` +2. `sudo -i -u postgres` +3. `psql` +4. `\c trailersafeguard_development` +5. ``` +DROP SCHEMA public CASCADE; +CREATE SCHEMA public; +GRANT ALL ON SCHEMA public TO postgres; +GRANT ALL ON SCHEMA public TO public; +COMMENT ON SCHEMA public IS 'standard public schema'; +``` +6. Steps 11 and 12 from **Quickstart**. \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..6af54c4 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,53 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # All Vagrant configuration is done here. The most common configuration + # options are documented and commented below. For a complete reference, + # please see the online documentation at vagrantup.com. + + # Every Vagrant virtual environment requires a box to build off of. + config.vm.box = "ubuntu/trusty64" + config.vm.hostname = "bikeshop-dev" + config.vm.provider "virtualbox" do |v| + v.name = "bikeshop-dev" + v.memory = 1024 + end + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # config.vm.network "forwarded_port", guest: 8000, host: 80 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + config.vm.network "private_network", ip: "192.168.33.45" + config.vm.hostname = "bikeshop.local" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + config.vm.synced_folder '.', '/vagrant', disabled: true + config.vm.synced_folder "bikeshop_project", "/srv/bikeshop", type: "nfs" + + config.vm.provision "ansible" do |ansible| + ansible.groups = { + "development" => "default" + } + ansible.playbook = "provision/site.yml" + # ansible.ask_sudo_pass = true + # ansible.verbose = "v" + ansible.sudo = true + ansible.host_key_checking = false + ansible.limit = "default" + ansible.extra_vars = { + ansible_ssh_user: 'vagrant', + ansible_connection: 'ssh', + ansible_ssh_args: '-o ForwardAgent=yes', + } + end +end diff --git a/bikeshop_project/.coveragerc b/bikeshop_project/.coveragerc new file mode 100644 index 0000000..9488fa2 --- /dev/null +++ b/bikeshop_project/.coveragerc @@ -0,0 +1,7 @@ +[report] +exclude_lines = + prama: no cover + + def __repr__ + + def __str__ \ No newline at end of file diff --git a/bikeshop_project/bikeshop/__init__.py b/bikeshop_project/bikeshop/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bikeshop_project/bikeshop/settings/__init__.py b/bikeshop_project/bikeshop/settings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bikeshop_project/bikeshop/settings/base.py b/bikeshop_project/bikeshop/settings/base.py new file mode 100644 index 0000000..f4207b6 --- /dev/null +++ b/bikeshop_project/bikeshop/settings/base.py @@ -0,0 +1,117 @@ +""" +Django settings for bikeshop project. + +Generated by 'django-admin startproject' using Django 1.9.4. + +For more information on this file, see +https://docs.djangoproject.com/en/1.9/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.9/ref/settings/ +""" + +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__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'registration', + 'core', +] + +MIDDLEWARE_CLASSES = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'bikeshop.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'bikeshop.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.9/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.9/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.9/howto/static-files/ + +STATIC_URL = '/static/' + +AUTH_USER_MODEL = 'registration.Member' \ No newline at end of file diff --git a/bikeshop_project/bikeshop/settings/development.py b/bikeshop_project/bikeshop/settings/development.py new file mode 100644 index 0000000..e604225 --- /dev/null +++ b/bikeshop_project/bikeshop/settings/development.py @@ -0,0 +1,47 @@ +from .base import * + + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = ')8(+b48*njk+e^8-l!6s3k4d=z(#g$v=)i^=_p-l*#-kk=!v_d' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'bikeshop_development', + 'USER': 'bikeshop', + 'PASSWORD': 'password', + 'HOST': '127.0.0.1', + 'PORT': '5432', + } +} + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'formatter': 'verbose' + }, + }, + 'formatters': { + 'verbose': { + 'format': '%(levelname)s %(asctime)s %(pathname)s %(message)s' + }, + }, + 'loggers': { + 'django': { + 'handlers': ['console'], + 'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'), + }, + 'bikeshop': { + 'handlers': ['console'], + 'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'), + } + }, +} diff --git a/bikeshop_project/bikeshop/urls.py b/bikeshop_project/bikeshop/urls.py new file mode 100644 index 0000000..c03f7d8 --- /dev/null +++ b/bikeshop_project/bikeshop/urls.py @@ -0,0 +1,21 @@ +"""bikeshop URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.9/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.conf.urls import url, include + 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) +""" +from django.conf.urls import url +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', admin.site.urls), +] diff --git a/bikeshop_project/bikeshop/wsgi.py b/bikeshop_project/bikeshop/wsgi.py new file mode 100644 index 0000000..1ac1cf5 --- /dev/null +++ b/bikeshop_project/bikeshop/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for bikeshop project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bikeshop.settings") + +application = get_wsgi_application() diff --git a/bikeshop_project/core/__init__.py b/bikeshop_project/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bikeshop_project/core/admin.py b/bikeshop_project/core/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/bikeshop_project/core/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/bikeshop_project/core/apps.py b/bikeshop_project/core/apps.py new file mode 100644 index 0000000..26f78a8 --- /dev/null +++ b/bikeshop_project/core/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + name = 'core' diff --git a/bikeshop_project/core/migrations/0001_initial.py b/bikeshop_project/core/migrations/0001_initial.py new file mode 100644 index 0000000..7c6d0f5 --- /dev/null +++ b/bikeshop_project/core/migrations/0001_initial.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-03-23 02:01 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Membership', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('renewed_at', models.DateTimeField(default=django.utils.timezone.now)), + ('safe_space', models.BooleanField(default=False)), + ('community', models.BooleanField(default=False)), + ('space', models.BooleanField(default=False)), + ('give_back', models.BooleanField(default=False)), + ('acknowledgement', models.BooleanField(default=False)), + ('member', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='membership', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/bikeshop_project/core/migrations/0002_payment.py b/bikeshop_project/core/migrations/0002_payment.py new file mode 100644 index 0000000..cec9bd3 --- /dev/null +++ b/bikeshop_project/core/migrations/0002_payment.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-03-23 02:27 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('CASH', 'cash'), ('CHEQUE', 'cheque'), ('VOLUNTEERING', 'volunteering'), ('STRIPE', 'stripe'), ('PAYPAL', 'paypal')], max_length=12)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('membership', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Membership')), + ], + ), + ] diff --git a/bikeshop_project/core/migrations/0003_visit.py b/bikeshop_project/core/migrations/0003_visit.py new file mode 100644 index 0000000..503d81d --- /dev/null +++ b/bikeshop_project/core/migrations/0003_visit.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-03-23 02:34 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('core', '0002_payment'), + ] + + operations = [ + migrations.CreateModel( + name='Visit', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('purpose', models.CharField(choices=[('VOLUNTEER', 'volunteer'), ('WORK', 'work on bike'), ('WORKSHOP', 'workshop')], max_length=50)), + ('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/bikeshop_project/core/migrations/__init__.py b/bikeshop_project/core/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bikeshop_project/core/models.py b/bikeshop_project/core/models.py new file mode 100644 index 0000000..8486fab --- /dev/null +++ b/bikeshop_project/core/models.py @@ -0,0 +1,49 @@ +from django.db import models +from django.utils import timezone + + +class Membership(models.Model): + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) + renewed_at = models.DateTimeField(default=timezone.now) + member = models.OneToOneField( + 'registration.Member', + on_delete=models.CASCADE, + related_name='membership' + ) + safe_space = models.BooleanField(default=False) + community = models.BooleanField(default=False) + space = models.BooleanField(default=False) + give_back = models.BooleanField(default=False) + # this should be a form field that requires the new member to type out there full name + acknowledgement = models.BooleanField(default=False) + + +class Payment(models.Model): + membership = models.ForeignKey( + 'Membership', + on_delete=models.CASCADE, + ) + payment_choices = ( + ('CASH', 'cash'), + ('CHEQUE', 'cheque'), + ('VOLUNTEERING', 'volunteering'), + ('STRIPE', 'stripe'), + ('PAYPAL', 'paypal') + ) + type = models.CharField(max_length=12, choices=payment_choices) + created_at = models.DateTimeField(auto_now_add=True) + + +class Visit(models.Model): + visit_choices = ( + ('VOLUNTEER', 'volunteer'), + ('WORK', 'work on bike'), + ('WORKSHOP', 'workshop') + ) + member = models.ForeignKey( + 'registration.Member', + on_delete=models.CASCADE + ) + created_at = models.DateTimeField(auto_now_add=True) + purpose = models.CharField(max_length=50, choices=visit_choices) diff --git a/bikeshop_project/core/tests.py b/bikeshop_project/core/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/bikeshop_project/core/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/bikeshop_project/core/views.py b/bikeshop_project/core/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/bikeshop_project/core/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/bikeshop_project/manage.py b/bikeshop_project/manage.py new file mode 100755 index 0000000..d5a6784 --- /dev/null +++ b/bikeshop_project/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bikeshop.settings.development") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/bikeshop_project/registration/__init__.py b/bikeshop_project/registration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bikeshop_project/registration/admin.py b/bikeshop_project/registration/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/bikeshop_project/registration/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/bikeshop_project/registration/apps.py b/bikeshop_project/registration/apps.py new file mode 100644 index 0000000..127d8e4 --- /dev/null +++ b/bikeshop_project/registration/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class RegistrationConfig(AppConfig): + name = 'registration' diff --git a/bikeshop_project/registration/migrations/0001_initial.py b/bikeshop_project/registration/migrations/0001_initial.py new file mode 100644 index 0000000..da6c081 --- /dev/null +++ b/bikeshop_project/registration/migrations/0001_initial.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-03-23 01:25 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0007_alter_validators_add_error_messages'), + ] + + operations = [ + migrations.CreateModel( + name='Member', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=255, unique=True, verbose_name='email address')), + ('first_name', models.CharField(max_length=255)), + ('last_name', models.CharField(max_length=255)), + ('preferred_name', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('guardian_name', models.CharField(blank=True, max_length=255, null=True)), + ('phone', models.CharField(blank=True, max_length=20, null=True)), + ('street', models.CharField(blank=True, max_length=255, null=True)), + ('city', models.CharField(blank=True, max_length=255, null=True)), + ('province', models.CharField(blank=True, max_length=255, null=True)), + ('country', models.CharField(blank=True, max_length=255, null=True)), + ('post_code', models.CharField(blank=True, max_length=20, null=True)), + ('self_identification', models.CharField(blank=True, max_length=255, null=True)), + ('gender', models.CharField(blank=True, max_length=255, null=True)), + ('involvement', models.CharField(blank=True, max_length=255, null=True)), + ('waiver', models.DateTimeField(blank=True, null=True)), + ('is_active', models.BooleanField(default=True)), + ('is_admin', models.BooleanField(default=False)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/bikeshop_project/registration/migrations/__init__.py b/bikeshop_project/registration/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bikeshop_project/registration/models.py b/bikeshop_project/registration/models.py new file mode 100644 index 0000000..238634e --- /dev/null +++ b/bikeshop_project/registration/models.py @@ -0,0 +1,87 @@ +from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin +from django.db import models + + +class CustomMemberManager(BaseUserManager): + def create_user(self, email, first_name, last_name, password=None): + """ + Creates and saves a User with the given email and password. + :param email: str + :param password: str + :param first_name: str + :param last_name: str + :return: object `CustomUser` + """ + if not email: + raise ValueError('Users must have an email address') + + user = self.model( + email=self.normalize_email(email), + ) + + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, email, password): + """ + Creates and saves a superuser with the given email, date of + birth and password. + :param email: str + :param password: str + :return: object `CustomUser` + """ + user = self.create_user(email, password=password) + user.is_admin = True + user.is_superuser = True + user.save(using=self._db) + return user + + +class Member(AbstractBaseUser, PermissionsMixin): + email = models.EmailField( + verbose_name='email address', + max_length=255, + unique=True, + ) + first_name = models.CharField(max_length=255, null=False) + last_name = models.CharField(max_length=255, null=False) + preferred_name = models.CharField(max_length=255, null=True, blank=True) + date_of_birth = models.DateField(null=True, blank=True) + guardian_name = models.CharField(max_length=255, null=True, blank=True) + phone = models.CharField(max_length=20, null=True, blank=True) + street = models.CharField(max_length=255, null=True, blank=True) + city = models.CharField(max_length=255, null=True, blank=True) + province = models.CharField(max_length=255, null=True, blank=True) + country = models.CharField(max_length=255, null=True, blank=True) + post_code = models.CharField(max_length=20, null=True, blank=True) + self_identification = models.CharField(max_length=255, null=True, blank=True) + gender = models.CharField(max_length=255, null=True, blank=True) + involvement = models.CharField(max_length=255, null=True, blank=True) + waiver = models.DateTimeField(null=True, blank=True) + is_active = models.BooleanField(default=True) + is_admin = models.BooleanField(default=False) + + objects = CustomMemberManager() + + USERNAME_FIELD = 'email' + # REQUIRED_FIELDS = [] + + def get_full_name(self): + # The user is identified by their email address + if self.first_name and self.last_name: + return '{0} {1}'.format(self.first_name, self.last_name) + else: + return self.email + + def get_short_name(self): + # The user is identified by their email address + return self.email + + def __str__(self): # __unicode__ on Python 2 + return self.email + + @property + def is_staff(self): + # Simplest possible answer: All admins are staff + return self.is_admin diff --git a/bikeshop_project/registration/tests.py b/bikeshop_project/registration/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/bikeshop_project/registration/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/bikeshop_project/registration/views.py b/bikeshop_project/registration/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/bikeshop_project/registration/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/package.json b/package.json new file mode 100644 index 0000000..bedaf4a --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "bikeshop", + "version": "0.0.1", + "description": "Maybe this isn't such a quick start, but it's the best I have right now. After the following steps are completed, you will have a working development version of the Trailer-Safeguard Django application connectable on [tsg-dev.local:8000/](http://tsg-dev.local:8000/).", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/provision/group_vars/all b/provision/group_vars/all new file mode 100644 index 0000000..8c7949c --- /dev/null +++ b/provision/group_vars/all @@ -0,0 +1,14 @@ +sudo: yes +# Application settings +app_name: bikeshop +app_user: "{{ app_name }}" +webapps_dir: /srv +settings_module: bikeshop.settings.{{ group_names[0] }} +app_dir: "{{ webapps_dir }}/{{ app_name }}" +venv: /opt/venv/{{ app_name }}-{{ group_names[0] }} + +db_name: "{{ app_name }}_development" +db_user: "{{ app_name }}" + +db_user_password: "{{ secret_db_user_password }}" +secret_db_user_password: password diff --git a/provision/group_vars/production/non-secrets.yml b/provision/group_vars/production/non-secrets.yml new file mode 100644 index 0000000..b2243f8 --- /dev/null +++ b/provision/group_vars/production/non-secrets.yml @@ -0,0 +1,11 @@ +postgresql_postgis: yes +app_dir: "{{ webapps_dir }}/{{ app_name }}" + +db_name: "{{ app_name }}_production" +db_user: "{{ app_name }}" + +db_user_password: "{{ secret_db_user_password }}" +django_key: "{{ secret_django_key }}" + +app_domain_name: shop.bcbc.bike +app_port: 9999 diff --git a/provision/group_vars/production/secrets.yml b/provision/group_vars/production/secrets.yml new file mode 100644 index 0000000..3dc5732 --- /dev/null +++ b/provision/group_vars/production/secrets.yml @@ -0,0 +1,10 @@ +$ANSIBLE_VAULT;1.1;AES256 +32363235643965636135663037643239343762353631383934636533373537666561373063353261 +6363393337636562653565303362366437313038633765330a396239336337356130353932656563 +64623464623637323736376665343539353634326636333134363961653431303065373337616238 +6633346461346266620a383536383331663262373736353230643736356134323136363230316136 +61353131326165346564626237306630323962366239653837323463653639616363303562396662 +32626165613563313130376438656561656664663231303839303935376335396533646534326661 +38306561303432326236346365353034663736376335616434633332313735383236396431636532 +36643163333762613065373861333265326363613365623330323135363739663931666466373961 +6362 diff --git a/provision/group_vars/staging/non-secrets.yml b/provision/group_vars/staging/non-secrets.yml new file mode 100644 index 0000000..af8ec43 --- /dev/null +++ b/provision/group_vars/staging/non-secrets.yml @@ -0,0 +1,10 @@ +postgresql_postgis: yes + +db_name: "{{ app_name }}_staging" +db_user: "{{ app_name }}" + +db_user_password: "{{ secret_db_user_password }}" +django_key: "{{ secret_django_key }}" + +app_domain_name: 9mile.local +app_port: 9998 diff --git a/provision/group_vars/staging/secrets.yml b/provision/group_vars/staging/secrets.yml new file mode 100644 index 0000000..8649c04 --- /dev/null +++ b/provision/group_vars/staging/secrets.yml @@ -0,0 +1,2 @@ +secret_db_user_password: password +secret_django_key: somekey \ No newline at end of file diff --git a/provision/inventories/production b/provision/inventories/production new file mode 100644 index 0000000..a2a5909 --- /dev/null +++ b/provision/inventories/production @@ -0,0 +1,5 @@ +[production] +1.1.1.1 ansible_ssh_private_key_file=~/.ssh/id_rsa + +[servers:children] +production diff --git a/provision/roles/app/tasks/main.yml b/provision/roles/app/tasks/main.yml new file mode 100644 index 0000000..0cd3aff --- /dev/null +++ b/provision/roles/app/tasks/main.yml @@ -0,0 +1,3 @@ +- include: prepare.yml +- include: virtualenv.yml + diff --git a/provision/roles/app/tasks/prepare.yml b/provision/roles/app/tasks/prepare.yml new file mode 100644 index 0000000..901c58a --- /dev/null +++ b/provision/roles/app/tasks/prepare.yml @@ -0,0 +1,5 @@ +--- +- name: create webapps log directory + action: file dest={{ webapps_dir }}/{{ app_name }}/log state=directory +- name: create webapps directory + action: file dest={{ webapps_dir }} state=directory \ No newline at end of file diff --git a/provision/roles/app/tasks/virtualenv.yml b/provision/roles/app/tasks/virtualenv.yml new file mode 100644 index 0000000..355ddb0 --- /dev/null +++ b/provision/roles/app/tasks/virtualenv.yml @@ -0,0 +1,15 @@ +--- +- name: install virtualenv + action: pip executable=pip3 name=virtualenv state=present + +- name: copy requirements + action: copy src=../requirements dest=/tmp + +- name: create virtual environment + action: file dest={{ venv }} state=directory + +- name: install requirements + action: pip executable=pip3 virtualenv={{ venv }} virtualenv_python=python3 requirements=/tmp/requirements/{{ group_names[0] }}.txt extra_args='--upgrade --force-reinstall' + register: requirements + tags: + - reqs diff --git a/provision/roles/app/templates/sparse-checkout b/provision/roles/app/templates/sparse-checkout new file mode 100644 index 0000000..14aeef7 --- /dev/null +++ b/provision/roles/app/templates/sparse-checkout @@ -0,0 +1,2 @@ +ninemilelegacy_project/core +ninemilelegacy_project/ninemilelegacy \ No newline at end of file diff --git a/provision/roles/common/tasks/main.yml b/provision/roles/common/tasks/main.yml new file mode 100644 index 0000000..ec069a2 --- /dev/null +++ b/provision/roles/common/tasks/main.yml @@ -0,0 +1,22 @@ +--- +- name: install packages needed to for building modules + action: apt update_cache=no pkg={{ item }} state=installed + with_items: + - build-essential + - autoconf + - git-core + +- name: install nginx webserver + action: apt update_cache=no pkg=nginx state=installed + +- name: install supervisord + action: apt update_cache=no pkg=supervisor state=installed + +- name: install postfix + action: apt update_cache=no pkg=postfix state=installed + +- name: install redis + action: apt name=redis-server update_cache=yes state=latest + +- name: create app user + action: user createhome=no name={{ app_name }} state=present diff --git a/provision/roles/database/tasks/main.yml b/provision/roles/database/tasks/main.yml new file mode 100644 index 0000000..3163948 --- /dev/null +++ b/provision/roles/database/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: create a postgresql database + sudo: yes + sudo_user: postgres + action: postgresql_db name={{ db_name }} template=template0 state=present + +- name: add a user to postgresql database + sudo: yes + sudo_user: postgres + action: postgresql_user db={{ db_name }} name={{ db_user }} password={{ db_user_password }} priv=ALL + +- name: ensure database backkup directory is present + sudo: yes + action: file path=/var/backups/{{ db_name }} state=directory owner=postgres + +- name: add a cron job to backup database every 1hr + sudo: yes + action: cron name='database backup' special_time=hourly user=postgres job='/usr/bin/pg_dump -Ft {{ db_name }} > /var/backups/{{ db_name }}/$(date +"\%Y\%m\%d\%H\%M\%S").tar' diff --git a/provision/roles/deploy-code/tasks/main.yml b/provision/roles/deploy-code/tasks/main.yml new file mode 100644 index 0000000..90bf449 --- /dev/null +++ b/provision/roles/deploy-code/tasks/main.yml @@ -0,0 +1,36 @@ +--- +- name: upload code + action: synchronize src=../bikeshop_project/ dest={{ app_dir }} + notify: restart supervisor + tags: + - deploy + +- name: user owns directory + action: file path={{ app_dir }} owner={{ app_name }} state=directory recurse=yes + tags: + - deploy + +- name: migrate database + action: django_manage command=migrate app_path={{ app_dir }} virtualenv={{ venv }} settings={{ settings_module }} + environment: + DJANGO_DB_PASSWORD: "{{ db_user_password }}" + DJANGO_SECRET_KEY: "{{ django_key }}" + tags: + - deploy + + +- name: collect static + action: django_manage command=collectstatic app_path={{ app_dir }} virtualenv={{ venv }} settings={{ settings_module }} + environment: + DJANGO_DB_PASSWORD: "{{ db_user_password }}" + DJANGO_SECRET_KEY: "{{ django_key }}" + tags: + - deploy + +- name: load initial data in to database + action: django_manage command=loaddata fixtures=authentication/fixtures/initial_data.json app_path={{ app_dir }} virtualenv={{ venv }} settings={{ settings_module }} + environment: + DJANGO_DB_PASSWORD: "{{ db_user_password }}" + DJANGO_SECRET_KEY: "{{ django_key }}" + tags: + - deploy diff --git a/provision/roles/django/tasks/main.yml b/provision/roles/django/tasks/main.yml new file mode 100644 index 0000000..51c14d5 --- /dev/null +++ b/provision/roles/django/tasks/main.yml @@ -0,0 +1,14 @@ +- name: migrate app + action: django_manage command=migrate app_path={{ app_dir }} settings={{ settings_module }} virtualenv={{ venv }} + ignore_errors: yes + environment: + SECRET_KEY: "{{ django_key }}" + DB_PASSWORD: "{{ db_user_password }}" + + +- name: collect static + action: django_manage command="collectstatic --noinput" app_path={{ app_dir }} settings={{ settings_module }} virtualenv={{ venv }} + ignore_errors: yes + environment: + SECRET_KEY: "{{ django_key }}" + DB_PASSWORD: "{{ db_user_password }}" diff --git a/provision/roles/handlers/main.yml b/provision/roles/handlers/main.yml new file mode 100644 index 0000000..93e130e --- /dev/null +++ b/provision/roles/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart supervisor + service: name=supervisor state=restarted \ No newline at end of file diff --git a/provision/roles/nginx/handlers/main.yml b/provision/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..3f5ca39 --- /dev/null +++ b/provision/roles/nginx/handlers/main.yml @@ -0,0 +1,2 @@ +- name: restart nginx + service: name=nginx state=restarted \ No newline at end of file diff --git a/provision/roles/nginx/tasks/main.yml b/provision/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..37b3545 --- /dev/null +++ b/provision/roles/nginx/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Configure nginx to run proxypass {{ app_name }} + action: template src={{ group_names[0] }}/nginx-site.conf dest=/etc/nginx/sites-available/{{ app_domain_name }} + notify: restart nginx + tags: + - nginx + +- name: Enable {{ app_name }} nginx config + action: file src=/etc/nginx/sites-available/{{ app_domain_name }} dest=/etc/nginx/sites-enabled/{{ app_domain_name }} state=link + notify: restart nginx + tags: + - nginx diff --git a/provision/roles/nginx/templates/production/nginx-site.conf b/provision/roles/nginx/templates/production/nginx-site.conf new file mode 100644 index 0000000..89006b7 --- /dev/null +++ b/provision/roles/nginx/templates/production/nginx-site.conf @@ -0,0 +1,61 @@ +server { + listen 80; + server_name www.{{ app_domain_name }}; + # $scheme will get the http protocol + # and 301 is best practice for tablet, phone, desktop and seo + return 301 https://{{ app_domain_name }}$request_uri; +} +server { + listen 80; + server_name {{ app_domain_name }}; + # $scheme will get the http protocol + # and 301 is best practice for tablet, phone, desktop and seo + return 301 https://{{ app_domain_name }}$request_uri; +} +server { + listen 443 ssl; + server_name {{ app_domain_name }}; + + ssl_certificate /etc/letsencrypt/live/{{ app_domain_name }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ app_domain_name }}/privkey.pem; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + + location = /favicon.ico { access_log off; log_not_found off; } + location /static/ { + root {{ app_dir }}/{{ app_name }}; + } + + location /media/ { + root {{ app_dir }}/{{ app_name }}; + } + + location / { + proxy_pass_header Server; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_connect_timeout 10; + proxy_read_timeout 10; + proxy_pass http://localhost:{{ app_port }}/; + } +} + +server { + listen 4051; + server_name events.{{ app_domain_name }}; + + location /incoming/spikeEvent.php { + proxy_pass_header Server; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_connect_timeout 10; + proxy_read_timeout 10; + proxy_pass http://localhost:{{ app_port }}/incoming/; + } +} diff --git a/provision/roles/nginx/templates/staging/nginx-site.conf b/provision/roles/nginx/templates/staging/nginx-site.conf new file mode 100644 index 0000000..c89954b --- /dev/null +++ b/provision/roles/nginx/templates/staging/nginx-site.conf @@ -0,0 +1,31 @@ +server { + listen 80; + server_name www.{{ app_domain_name }}; + # $scheme will get the http protocol + # and 301 is best practice for tablet, phone, desktop and seo + return 301 $scheme://{{ app_domain_name }}$request_uri; +} +server { + listen 80; + server_name {{ app_domain_name }}; + + location = /favicon.ico { access_log off; log_not_found off; } + location /static/ { + root {{ app_dir }}; + } + + location /media/ { + root {{ app_dir }}; + } + + location / { + proxy_pass_header Server; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_connect_timeout 10; + proxy_read_timeout 10; + proxy_pass http://localhost:{{ app_port }}/; + } +} diff --git a/provision/roles/python/tasks/main.yml b/provision/roles/python/tasks/main.yml new file mode 100644 index 0000000..f50e65c --- /dev/null +++ b/provision/roles/python/tasks/main.yml @@ -0,0 +1,14 @@ +--- +- name: install common packages needed for Python application development with PostgreSQL + action: apt update_cache=yes pkg={{ item }} state=installed + with_items: + - python3-dev + - python3-psycopg2 + - python3-setuptools + - python3-pip + - libpq-dev + - libxml2-dev + - libxslt1-dev + +#- name: install superlance (supervisor plugins) +# action: pip3 name=superlance diff --git a/provision/roles/supervisor/handlers/main.yml b/provision/roles/supervisor/handlers/main.yml new file mode 100644 index 0000000..daa253e --- /dev/null +++ b/provision/roles/supervisor/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: start supervisor + service: name=supervisor state=started diff --git a/provision/roles/supervisor/tasks/main.yml b/provision/roles/supervisor/tasks/main.yml new file mode 100644 index 0000000..52e5751 --- /dev/null +++ b/provision/roles/supervisor/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Configure supvervisor to run {{ app_name }} + action: template src={{ group_names[0] }}/supervisor-program.conf dest=/etc/supervisor/conf.d/{{ app_name }}.conf + tags: + - supervisor + - deploy + +- name: Load and re-read group configs + action: supervisorctl name='{{ app_name }}:' state=present config=/etc/supervisor/supervisord.conf + tags: + - supvervisor + - deploy diff --git a/provision/roles/supervisor/tasks/staging/main.yml b/provision/roles/supervisor/tasks/staging/main.yml new file mode 100644 index 0000000..1b38cde --- /dev/null +++ b/provision/roles/supervisor/tasks/staging/main.yml @@ -0,0 +1,4 @@ +--- +- name: Configure supvervisor to run {{ app_name }} + action: template src=staging/supervisor-program.conf dest=/etc/supervisor/conf.d/{{ app_name }}.conf + notify: restart supervisor diff --git a/provision/roles/supervisor/templates/production/supervisor-program.conf b/provision/roles/supervisor/templates/production/supervisor-program.conf new file mode 100644 index 0000000..7d56e5e --- /dev/null +++ b/provision/roles/supervisor/templates/production/supervisor-program.conf @@ -0,0 +1,45 @@ +[group:{{ app_name }}] +programs=django,celerybeat,celeryworker +[program:django] +command={{ venv }}/bin/gunicorn -b 127.0.0.1:{{ app_port }} {{ app_name }}.wsgi:application +directory={{ app_dir }} +environment=DJANGO_DB_PASSWORD="{{ db_user_password }}",DJANGO_SECRET_KEY="{{ django_key }}",DJANGO_SETTINGS_MODULE="{{ settings_module }}" +autostart=true +autorestart=true +redirect_stderr=true +user={{ app_name }} + +[program:celerybeat] +command={{ venv }}/bin/celery -A {{ app_name }} beat +environment=DJANGO_DB_PASSWORD="{{ db_user_password }}",DJANGO_SECRET_KEY="{{ django_key }}",DJANGO_SETTINGS_MODULE="{{ settings_module }}" +directory={{ app_dir }} +autostart=true +autorestart=true +redirect_stderr=true +user={{ app_name }} + +[program:celeryworker] +command={{ venv }}/bin/celery -A {{ app_name }} worker +environment=DJANGO_DB_PASSWORD="{{ db_user_password }}",DJANGO_SECRET_KEY="{{ django_key }}",DJANGO_SETTINGS_MODULE="{{ settings_module }}",PYTHON_PATH={{ app_dir }} +directory={{ app_dir }} +autostart=true +autorestart=true +stdout_logfile=/var/log/celeryd/{{ app_name }}.log +stderr_logfile=/var/log/celeryd/{{ app_name }}.log +user={{ app_name }} +numprocs=1 + +startsecs=10 + +; Need to wait for currently executing tasks to finish at shutdown. +; Increase this if you have very long running tasks. +stopwaitsecs = 600 + +; When resorting to send SIGKILL to the program to terminate it +; send SIGKILL to its whole process group instead, +; taking care of its children as well. +killasgroup=true + +; Set Celery priority higher than default (999) +; so, if rabbitmq is supervised, it will start first. +priority=1000 diff --git a/provision/roles/supervisor/templates/staging/supervisor-program.conf b/provision/roles/supervisor/templates/staging/supervisor-program.conf new file mode 100644 index 0000000..202ef91 --- /dev/null +++ b/provision/roles/supervisor/templates/staging/supervisor-program.conf @@ -0,0 +1,10 @@ +[program:{{ app_name }}] +command={{ venv }}/bin/gunicorn -b 127.0.0.1:{{ app_port }} {{ app_name }}.wsgi:application +directory={{ app_dir }} +environment=DB_PASSWORD="{{ db_user_password }}",DJANGO_SECRET_KEY="{{ django_key }}",DJANGO_SETTINGS_MODULE="{{settings_module}}" +autorestart=true +redirect_stderr=true + +[eventlistener:memmon] +command=memmon -p {{ app_name }}=50MB -m vagrant@{{ app_domain_name}} +events=TICK_60 diff --git a/provision/roles/tasks/main.yml b/provision/roles/tasks/main.yml new file mode 100644 index 0000000..11c5842 --- /dev/null +++ b/provision/roles/tasks/main.yml @@ -0,0 +1,4 @@ +--- +- name: Configure supvervisor to run {{ app_name }} + action: template src={{ group_names[0] }}/supervisor-program.conf dest=/etc/supervisor/conf.d/{{ app_name }}.conf + notify: restart supervisor diff --git a/provision/roles/tasks/staging/main.yml b/provision/roles/tasks/staging/main.yml new file mode 100644 index 0000000..1b38cde --- /dev/null +++ b/provision/roles/tasks/staging/main.yml @@ -0,0 +1,4 @@ +--- +- name: Configure supvervisor to run {{ app_name }} + action: template src=staging/supervisor-program.conf dest=/etc/supervisor/conf.d/{{ app_name }}.conf + notify: restart supervisor diff --git a/provision/roles/templates/production/supervisor-program.conf b/provision/roles/templates/production/supervisor-program.conf new file mode 100644 index 0000000..93de037 --- /dev/null +++ b/provision/roles/templates/production/supervisor-program.conf @@ -0,0 +1,11 @@ +[program:{{ app_name }}] +command={{ venv }}/bin/gunicorn -b 127.0.0.1:{{ app_port }} boxoffice.wsgi:application +directory={{ app_dir }} +environment=DB_PASSWORD="{{ db_user_password }}",OTB_SECRET_KEY="{{ django_key }}" +autostart=true +autorestart=true +redirect_stderr=true + +[eventlistener:memmon] +command=memmon -p {{ app_name }}=50MB -m root +events=TICK_60 diff --git a/provision/roles/templates/staging/supervisor-program.conf b/provision/roles/templates/staging/supervisor-program.conf new file mode 100644 index 0000000..d457adc --- /dev/null +++ b/provision/roles/templates/staging/supervisor-program.conf @@ -0,0 +1,10 @@ +[program:{{ app_name }}] +command={{ venv }}/bin/gunicorn -b 127.0.0.1:{{ app_port }} boxoffice.wsgi:application +directory={{ app_dir }} +environment=DB_PASSWORD="{{ db_user_password }}",OTB_SECRET_KEY="{{ django_key }}",DJANGO_SETTINGS_MODULE="boxoffice.settings.staging" +autorestart=true +redirect_stderr=true + +[eventlistener:memmon] +command=memmon -p {{ app_name }}=50MB -m vagrant@ontheboards.local +events=TICK_60 diff --git a/provision/roles/zenoamaro.postgresql/.gitignore b/provision/roles/zenoamaro.postgresql/.gitignore new file mode 100644 index 0000000..fa075d1 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/.gitignore @@ -0,0 +1 @@ +/.vagrant/ \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/.travis.yml b/provision/roles/zenoamaro.postgresql/.travis.yml new file mode 100644 index 0000000..7ecee5d --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/.travis.yml @@ -0,0 +1,28 @@ +--- + +# Configuration directives for Travis CI +# -------------------------------------- + +# See the Travis documentation for help on writing this file. + +# [Travis CI] http://travis-ci.org +# [configuration] http://about.travis-ci.org/docs/user/build-configuration/ + + +language: python # Needed to run ansible + +python: + - "2.7" + +install: + - pip install ansible + +script: + # Syntax check every ansible playbook in root + # Don't check main, though, as vars_prompt still + # trigger during syntax checks, and travis fails + - find . -maxdepth 1 -type f -name '*.yml' -not -name '.*' -not -name 'main.yml' | xargs -t -n1 ansible-playbook --syntax-check -i inventory + +notifications: + email: + - zenoamaro@gmail.com \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/LICENSE.md b/provision/roles/zenoamaro.postgresql/LICENSE.md new file mode 100644 index 0000000..5ca1126 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, zenoamaro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/README.md b/provision/roles/zenoamaro.postgresql/README.md new file mode 100644 index 0000000..f4f68fc --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/README.md @@ -0,0 +1,117 @@ +PostgreSQL role for Ansible +=========================== + +A role for deploying and configuring [PostgreSQL](http://www.postgresql.org/) and extensions on unix hosts using [Ansible](http://www.ansibleworks.com/). + +It can additionally be used as a playbook for quickly provisioning hosts. + +Vagrant machines are provided to produce a boxed install of PostgreSQL or a VM for integration testing. + + +Supports +-------- +Supported PostgreSQL versions: + +- PostgreSQL 9.4 +- PostgreSQL 9.3 + +Supported targets: +- Ubuntu 14.04 LTS "Trusty Tahr" +- Ubuntu 12.04 LTS "Precise Pangolin" +- Debian (untested) +- RedHat (untested) + +Installation methods: + +- Binary packages from the official repositories at [postgresql.org](http://www.postgresql.org/download/) + +Available extensions (under a switch): + +- Development headers - `postgresql_dev_headers` +- Contrib modules - `postgresql_contrib` +- [PostGIS](http://postgis.net/) - `postgresql_postgis` + + +Usage +----- +Clone this repo into your roles directory: + + $ git clone https://github.com/zenoamaro/ansible-postgresql.git roles/postgresql + +And add it to your play's roles: + + - hosts: ... + roles: + - postgresql + - ... + +This roles comes preloaded with almost every available default. You can override each one in your hosts/group vars, in your inventory, or in your play. See the annotated defaults in `defaults/main.yml` for help in configuration. All provided variables start with `postgresql_`. + +You can also use the role as a playbook. You will be asked which hosts to provision, and you can further configure the play by using `--extra-vars`. + + $ ansible-playbook -i inventory --extra-vars='{...}' main.yml + +To provision a standalone PostgreSQL box, start the `boxed` VM, which is a Ubuntu 12.04 box: + + $ vagrant up boxed + +You will find PostgreSQL listening on the VM's `5432` port on address `192.168.33.20` in the private network. You can then connect to it as any user. Please note that this is highly insecure, so if you're going to publish this VM you'll want to provide actual authentication. + +Run the tests by provisioning the appropriate VM: + + $ vagrant up test-ubuntu-trusty + +At the moment, the following test boxes are available: + +- `test-ubuntu-precise` +- `test-ubuntu-trusty` + + +Still to do +----------- +- Add repositories, tasks and test VMs for other distros +- Allow installation from sources if requested +- Add support for different PostgreSQL versions (9.4+) +- Add support for PostgreSQL clusters +- Add support for [PgBouncer](http://wiki.postgresql.org/wiki/PgBouncer) +- Try to make the boxed VM more secure by default +- Add links to the relevant documentation in configuration files +- Provide a library of custom modules + + +Changelog +--------- +### 0.1.2 +- Installing less dependencies, and later in the process. + +### 0.1.1 +- The package list is not being updated in playbooks anymore. +- Added more test machines. + +### 0.1 +Initial version. + + +License +------- +The MIT License (MIT) + +Copyright (c) 2015, zenoamaro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/Vagrantfile b/provision/roles/zenoamaro.postgresql/Vagrantfile new file mode 100644 index 0000000..caec245 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/Vagrantfile @@ -0,0 +1,62 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure '2' do |config| + + +# Standalone box +# -------------- + + # Provision this machine to obtain a standalone box + # listening on the default ports. + + config.vm.define 'boxed' do |box| + box.vm.box = "ubuntu/trusty64" + # Configure the network topology to your needs + config.vm.network :private_network, ip: "192.168.33.10" + # config.vm.network :public_network + config.vm.provision :ansible do |ansible| + ansible.playbook = './boxed.yml' + ansible.inventory_path = './inventory' + end + # Forward this postgres to a port on the host + config.vm.network :forwarded_port, guest: 5432, host: 15432 + # TODO: What about also forwarding the data storage? + end + + +# Test machines +# ------------- + + # These test machines will configure the installation with all + # its extensions enabled, in order to test the validity + # of the role. + + # Ubuntu machines are available: + # - "test-ubuntu-precise" + # - "test-ubuntu-trusty" + + def apply_test_ansible_defaults(ansible) + ansible.playbook = './test.yml' + ansible.inventory_path = './inventory' + end + + config.vm.define 'test-ubuntu-trusty', autostart:false do |box| + box.vm.box = "ubuntu/trusty64" + config.vm.network :private_network, ip: "192.168.33.21" + config.vm.provision :ansible do |ansible| + apply_test_ansible_defaults ansible + ansible.extra_vars = {} + end + end + + config.vm.define 'test-ubuntu-precise', autostart:false do |box| + box.vm.box = "ubuntu/precise64" + config.vm.network :private_network, ip: "192.168.33.20" + config.vm.provision :ansible do |ansible| + apply_test_ansible_defaults ansible + ansible.extra_vars = {} + end + end + +end diff --git a/provision/roles/zenoamaro.postgresql/boxed.yml b/provision/roles/zenoamaro.postgresql/boxed.yml new file mode 100644 index 0000000..c538561 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/boxed.yml @@ -0,0 +1,26 @@ +--- + +# Boxed installation playbook +# --------------------------- + +# A Simple, straight playbook for producing +# a boxed installation in a vagrant VM. + + +- name: 'PostgreSQL boxed installation' + + hosts: vagrant + + vars: + postgresql_listen_addresses: + - '*' + postgresql_authentication: + - type: host + user: all + database: all + address: '0.0.0.0/0' + method: trust + + roles: + - '.' # This role itself + diff --git a/provision/roles/zenoamaro.postgresql/defaults/main.yml b/provision/roles/zenoamaro.postgresql/defaults/main.yml new file mode 100644 index 0000000..3eb699f --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/defaults/main.yml @@ -0,0 +1,606 @@ +--- + +postgresql_version: 9.4 + +# This will be the main admin user, which is only allowed to connect +# from localhost, mainly for provisioning, maintenance and scripts. +postgresql_admin_user: postgres +postgresql_admin_group: "{{postgresql_admin_user}}" + +# TODO: This has been modeled but there's no real support for clusters yet +postgresql_cluster: main + + +# File locations +# -------------- + + +# Store postgres' configuration files here +postgresql_conf_directory: "/etc/postgresql/{{postgresql_version}}/{{postgresql_cluster}}" +# Host-based authentication file +postgresql_hba_file: "{{postgresql_conf_directory}}/pg_hba.conf" +# Ident configuration file +postgresql_ident_file: "{{postgresql_conf_directory}}/pg_ident.conf" +# Use data in another directory +postgresql_data_directory: "/var/lib/postgresql/{{postgresql_version}}/{{postgresql_cluster}}" +# Directory to store runtime data such as PIDs +postgresql_runtime_directory: "/var/run/postgresql" +# If external_pid_file is not explicitly set, on extra PID file is written +postgresql_external_pid_file: "{{postgresql_runtime_directory}}/{{postgresql_version}}-{{postgresql_cluster}}.pid" +# Store postgresql's logs files here +postgresql_log_directory: "/var/log/postgresql" + + +# Connections and authentication +# ------------------------------ + +# Use 'localhost' for local addresses only. Use '*' alone to +# listen on every available address. +postgresql_listen_addresses: + - localhost +postgresql_port: 5432 + +# Authenticated connections that will be inserted in `pg_hba.conf`. +# These won't overwrite the default local idents, which are left +# untouched as they are useful and safe. +# +# Specify connections as a list of hashes having this schema: +# - type: local +# user: postgres +# method: peer +# database: 'all' # defaults to 'samerole', can also be a list +# address: '192.168.0.0/24' # optional +# options: # optional +# key: value +# +# The first field is the connection type: "local" is a Unix-domain +# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, +# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a +# plain TCP/IP socket. +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", +# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that +# "password" sends passwords in clear text; "md5" is preferred since +# it sends encrypted passwords. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +postgresql_authentication: [] + +# Authenticated connections that will be inserted in `pg_hba.conf`. +# These won't overwrite the default local idents, which are left +# untouched as they are useful and safe. +# Specify connections as a list of hashes having this schema: +# - name: map_a +# user: system_user +# pg_user: postgresql_user +postgresql_user_map: [] + +# A dict whose `key: value`s will be provided as environment +# variables for the postmaster. +postgresql_env: {} + +# Note: Increasing max_connections costs ~400 bytes of shared memory per +# connection slot, plus lock space (see max_locks_per_transaction). +postgresql_max_connections: 1024 +postgresql_superuser_reserved_connections: 3 + +postgresql_unix_socket_directories: # comma-separated list of directories + - /var/run/postgresql +postgresql_unix_socket_group: '' +postgresql_unix_socket_permissions: '0777' # begin with 0 to use octal notation + +# Automatic pg_ctl configuration. Specify a list of options containing +# cluster specific options to be passed to pg_ctl(1). +postgresql_pg_ctl_options: [] + +postgresql_bonjour: off # advertise server via Bonjour +postgresql_bonjour_name: '' # defaults to the computer name + + +# Security and Authentication +# --------------------------- + +postgresql_authentication_timeout: 60s +postgresql_ssl: off +postgresql_ssl_ciphers: + - 'DEFAULT' + - '!LOW' + - '!EXP' + - '!MD5' + - '@STRENGTH' +postgresql_ssl_renegotiation_limit: 512MB # amount of data between renegotiations +postgresql_ssl_cert_file: /etc/ssl/certs/ssl-cert-snakeoil.pem +postgresql_ssl_key_file: /etc/ssl/private/ssl-cert-snakeoil.key +postgresql_ssl_ca_file: '' +postgresql_ssl_crl_file: '' +postgresql_password_encryption: on +postgresql_db_user_namespace: off + +# Kerberos and GSSAPI +postgresql_krb_server_keyfile: '' +postgresql_krb_caseins_users: off + +# TCP Keepalives, 0 selects the system default +postgresql_tcp_keepalives_idle: 0 +postgresql_tcp_keepalives_interval: 0 +postgresql_tcp_keepalives_count: 0 + + +# Memory +# ------ + +postgresql_shared_buffers: 128MB # min 128kB +postgresql_temp_buffers: 8MB # min 800kB +postgresql_work_mem: 1MB # min 64kB +postgresql_maintenance_work_mem: 16MB # min 1MB +postgresql_max_stack_depth: 2MB # min 100kB + +# Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory +# per transaction slot, plus lock space (see max_locks_per_transaction). +# It is not advisable to set max_prepared_transactions nonzero unless you +# actively intend to use prepared transactions. +postgresql_max_prepared_transactions: 0 # zero disables the feature + +# Disk +# ---- + +# limits per-session temp file space in kB, or -1 for off limit +postgresql_temp_file_limit: -1 + +# Kernel Resource Usage +# --------------------- + +postgresql_max_files_per_process: 1000 # min 25 +postgresql_shared_preload_libraries: [] + + +# Lock Management +# --------------- + +postgresql_deadlock_timeout: 1s +postgresql_max_locks_per_transaction: 64 # min 10 + +# Note: Each lock table slot uses ~270 bytes of shared memory, and there are +# max_locks_per_transaction * (max_connections + max_prepared_transactions) +# lock table slots. +postgresql_max_pred_locks_per_transaction: 64 # min 10 + + +# Write Ahead Log +# --------------- + +postgresql_wal_level: minimal # minimal, archive, or hot_standby +postgresql_fsync: on # turns forced synchronization on or off + +# Synchronization level: +# - off +# - local +# - remote_write +# - on +postgresql_synchronous_commit: on + +# The default is the first option supported by the operating system: +# - open_datasync +# - fdatasync (default on Linux) +# - fsync +# - fsync_writethrough +# - open_sync +postgresql_wal_sync_method: fsync + +# recover from partial page writes +postgresql_full_page_writes: on + +postgresql_wal_buffers: -1 # min 32kB, -1 sets based on shared_buffers +postgresql_wal_writer_delay: 200ms # 1-10000 milliseconds +postgresql_commit_delay: 0 # range 0-100000, in microseconds +postgresql_commit_siblings: 5 # range 1-1000 + +postgresql_checkpoint_segments: 3 # in logfile segments, min 1, 16MB each +postgresql_checkpoint_timeout: 5min # range 30s-1h +postgresql_checkpoint_completion_target: 0.5 # checkpoint target duration, 0.0 - 1.0 +postgresql_checkpoint_warning: 30s # 0 disables + +# allows archiving to be done +postgresql_archive_mode: off + +# Command to use to archive a logfile segment. +# Placeholders: %p = path of file to archive +# %f = file name only +# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +postgresql_archive_command: '' + +# force a logfile segment switch after this +postgresql_archive_timeout: 0 + + +# Replication +# ----------- + +# Set these on the master and on any standby that will send replication data. + +# max number of walsender processes +postgresql_max_wal_senders: 0 + +postgresql_wal_keep_segments: 0 # in logfile segments, 16MB each; 0 disables +postgresql_wal_sender_timeout: 60s # in milliseconds; 0 disables + +# Replication (masters) +# --------------------- + +# These settings are ignored on a standby server. + +# Standby servers that provide sync rep. +# Comma-separated list of application_name from standby(s) +postgresql_synchronous_standby_names: [] # '*' means 'all' + +# number of xacts by which cleanup is delayed +postgresql_vacuum_defer_cleanup_age: 0 + +# "on" allows queries during recovery +postgresql_hot_standby: off +# max delay before canceling queries when reading WAL from archive +postgresql_max_standby_archive_delay: 30s # -1 allows indefinite delay +# max delay before canceling queries when reading streaming WAL; +postgresql_max_standby_streaming_delay: 30s # -1 allows indefinite delay +# send replies at least this often +postgresql_wal_receiver_status_interval: 10s # 0 disables +# send info from standby to prevent query conflicts +postgresql_hot_standby_feedback: off +#time that receiver waits for communication from master in milliseconds +postgresql_wal_receiver_timeout: 60s + + +# Error Reporting And Logging +# --------------------------- + +# Valid values are combinations of stderr, csvlog, syslog, and eventlog. +# depending on platform. Csvlog requires logging_collector to be on. +postgresql_log_destination: stderr + +# Enable capturing of stderr and csvlog into log files. +# Required to be on for csvlogs. +postgresql_logging_collector: on + +# These are only used if logging_collector is on: + +# Log file name pattern, can include strftime() escapes +postgresql_log_filename: postgresql-%Y-%m-%d_%H%M%S.log +postgresql_log_file_mode: '0600' # begin with 0 to use octal notation +# If on, an existing log file with the same name as the new log file will be +# truncated rather than appended to. But such truncation only occurs on +# time-driven rotation, not on restarts or size-driven rotation. Default is +# off, meaning append to existing files in all cases. +postgresql_log_truncate_on_rotation: off +# Automatic rotation of logfiles will happen after that time. +postgresql_log_rotation_age: 1d +# Automatic rotation of logfiles will happen after that much log output. +postgresql_log_rotation_size: 10MB + +# These are relevant when logging to syslog: +postgresql_syslog_facility: LOCAL0 +postgresql_syslog_ident: postgres +# This is only relevant when logging to eventlog (win32): +postgresql_event_source: PostgreSQL + +# Values in order of decreasing detail: +# - debug5 +# - debug4 +# - debug3 +# - debug2 +# - debug1 +# - log +# - notice +# - warning +# - error +postgresql_client_min_messages: notice + +# Values in order of decreasing detail: +# - debug5 +# - debug4 +# - debug3 +# - debug2 +# - debug1 +# - info +# - notice +# - warning +# - error +# - log +# - fatal +# - panic +postgresql_log_min_messages: warning + +# Values in order of decreasing detail: +# - debug5 +# - debug4 +# - debug3 +# - debug2 +# - debug1 +# - info +# - notice +# - warning +# - error +# - log +# - fatal +# - panic (effectively off) +postgresql_log_min_error_statement: error + +# -1 is disabled, 0 logs all statements and their durations, > 0 logs only +# statements running at least this number of milliseconds +postgresql_log_min_duration_statement: -1 + +postgresql_debug_print_parse: off +postgresql_debug_print_rewritten: off +postgresql_debug_print_plan: off +postgresql_debug_pretty_print: on +postgresql_log_checkpoints: off +postgresql_log_connections: off +postgresql_log_disconnections: off +postgresql_log_duration: off +postgresql_log_error_verbosity: default # terse, default, or verbose messages +postgresql_log_hostname: off + +# Special values: +# %a = application name +# %u = user name +# %d = database name +# %r = remote host and port +# %h = remote host +# %p = process ID +# %t = timestamp without milliseconds +# %m = timestamp with milliseconds +# %i = command tag +# %e = SQL state +# %c = session ID +# %l = session line number +# %s = sessioan start timestamp +# %v = virtual transaction ID +# %x = transaction ID (0 if none) +# %q = stop here in non-session +# processes +# %% = '%' +postgresql_log_line_prefix: '%t ' + +# log lock waits >= deadlock_timeout +postgresql_log_lock_waits: off +postgresql_log_statement: none # none, ddl, mod, all +# log temporary files equal or larger +postgresql_log_temp_files: -1 +postgresql_log_timezone: UTC + + +# Runtime statistics +# ------------------ + +postgresql_track_activities: on +postgresql_track_counts: on +postgresql_track_io_timing: off +postgresql_track_functions: none # none, pl, all +postgresql_track_activity_query_size: 1024 +postgresql_update_process_title: on +postgresql_stats_temp_directory: pg_stat_tmp + +postgresql_log_parser_stats: off +postgresql_log_planner_stats: off +postgresql_log_executor_stats: off +postgresql_log_statement_stats: off + + +# Error Handling +# -------------- + +# Terminate session on any error? +postgresql_exit_on_error: off +# Reinitialize after backend crash? +postgresql_restart_after_crash: on + + +# Query Tuning (Planner) +# ---------------------- + +postgresql_enable_bitmapscan: on +postgresql_enable_hashagg: on +postgresql_enable_hashjoin: on +postgresql_enable_indexscan: on +postgresql_enable_indexonlyscan: on +postgresql_enable_material: on +postgresql_enable_mergejoin: on +postgresql_enable_nestloop: on +postgresql_enable_seqscan: on +postgresql_enable_sort: on +postgresql_enable_tidscan: on + +postgresql_seq_page_cost: 1.0 # measured on an arbitrary scale +postgresql_random_page_cost: 4.0 # same scale as above +postgresql_cpu_tuple_cost: 0.01 # same scale as above +postgresql_cpu_index_tuple_cost: 0.005 # same scale as above +postgresql_cpu_operator_cost: 0.0025 # same scale as above +postgresql_effective_cache_size: 128MB + +# Query Tuning (Genetic Query Optimizer) +# -------------------------------------- + +postgresql_geqo: on +postgresql_geqo_threshold: 12 +postgresql_geqo_effort: 5 # range 1-10 +postgresql_geqo_pool_size: 0 # selects default based on effort +postgresql_geqo_generations: 0 # selects default based on effort +postgresql_geqo_selection_bias: 2.0 # range 1.5-2.0 +postgresql_geqo_seed: 0.0 # range 0.0-1.0 + +# Query Tuning (Other Planner Options) +# ------------------------------------ + +postgresql_default_statistics_target: 100 # range 1-10000 +postgresql_constraint_exclusion: partition # on, off, or partition +postgresql_cursor_tuple_fraction: 0.1 # range 0.0-1.0 +postgresql_from_collapse_limit: 8 +postgresql_join_collapse_limit: 8 # 1 disables collapsing of explicit + + +# Cost-Based Vacuum Delay +# ----------------------- + +postgresql_vacuum_cost_delay: 0 # 0-100 milliseconds +postgresql_vacuum_cost_page_hit: 1 # 0-10000 credits +postgresql_vacuum_cost_page_miss: 10 # 0-10000 credits +postgresql_vacuum_cost_page_dirty: 20 # 0-10000 credits +postgresql_vacuum_cost_limit: 200 # 1-10000 credits + + +# Autovacuum Parameters +# --------------------- + +# Enable autovacuum subprocess? 'on' requires track_counts to also be on. +postgresql_autovacuum: on +# -1 disables, 0 logs all actions and their durations, > 0 logs only +# actions running at least this number of milliseconds. +postgresql_log_autovacuum_min_duration: -1 +# max number of autovacuum subprocesses +postgresql_autovacuum_max_workers: 3 +# time between autovacuum runs +postgresql_autovacuum_naptime: 1min +# min number of row updates before vacuum +postgresql_autovacuum_vacuum_threshold: 50 +# min number of row updates before analyze +postgresql_autovacuum_analyze_threshold: 50 +# fraction of table size before vacuum +postgresql_autovacuum_vacuum_scale_factor: 0.2 +# fraction of table size before analyze +postgresql_autovacuum_analyze_scale_factor: 0.1 +# maximum XID age before forced vacuum +postgresql_autovacuum_freeze_max_age: 200000000 +# default vacuum cost delay for autovacuum, in milliseconds +postgresql_autovacuum_vacuum_cost_delay: 20ms +# default vacuum cost limit for autovacuum, +postgresql_autovacuum_vacuum_cost_limit: -1 + + +# Background Writer +# ----------------- + +postgresql_bgwriter_delay: 200ms # 10-10000ms between rounds +postgresql_bgwriter_lru_maxpages: 100 # 0-1000 max buffers written/round +postgresql_bgwriter_lru_multiplier: 2.0 # 0-10.0 multipler on buffers scanned/round + + +# Asynchronous Behavior +# --------------------- + +postgresql_effective_io_concurrency: 1 # 1-1000; 0 disables prefetching + + +# Client Connection Defaults +# -------------------------- + +postgresql_search_path: # schema names + - '"$user"' + - public +postgresql_default_tablespace: '' # a tablespace name, '' uses the default +postgresql_temp_tablespaces: [] # a list of tablespace names + +postgresql_check_function_bodies: on +postgresql_default_transaction_isolation: read committed +postgresql_default_transaction_read_only: off +postgresql_default_transaction_deferrable: off +postgresql_session_replication_role: origin + +postgresql_statement_timeout: 0 # in milliseconds, 0 is disabled +postgresql_lock_timeout: 0 # in milliseconds, 0 is disabled +postgresql_vacuum_freeze_min_age: 50000000 +postgresql_vacuum_freeze_table_age: 150000000 + +postgresql_bytea_output: hex # hex, escape +postgresql_xmlbinary: base64 +postgresql_xmloption: content + +# Select the set of available time zone abbreviations. Currently, there are: +# Default +# Australia +# India +# You can create your own file in `share/timezonesets/`. +postgresql_timezone_abbreviations: Default + +postgresql_datestyle: + - iso + - mdy +postgresql_intervalstyle: postgres +postgresql_timezone: UTC +postgresql_extra_float_digits: 0 # min -15, max 3 +postgresql_client_encoding: sql_ascii # 'sql_ascii' actually defaults to database encoding + +# These settings are initialized by initdb, but they can be changed. + +# locale for system error message +postgresql_lc_messages: en_US.UTF-8 +# locale for monetary formatting +postgresql_lc_monetary: en_US.UTF-8 +# locale for number formatting +postgresql_lc_numeric: en_US.UTF-8 +# locale for time formatting +postgresql_lc_time: en_US.UTF-8 + +postgresql_default_text_search_config: pg_catalog.english + +postgresql_dynamic_library_path: '$libdir' +postgresql_local_preload_libraries: [] + + +# Version/platform Compatibility +# ------------------------------ + +postgresql_array_nulls: on +postgresql_backslash_quote: safe_encoding # on, off, or safe_encoding +postgresql_default_with_oids: off +postgresql_escape_string_warning: on +postgresql_lo_compat_privileges: off +postgresql_quote_all_identifiers: off +postgresql_sql_inheritance: on +postgresql_standard_conforming_strings: on +postgresql_synchronize_seqscans: on +postgresql_transform_null_equals: off + + +# Extensions +# ---------- + +# If enabled, this will install the contrib packages. + +postgresql_contrib: no + + +# If enabled, will install the [PostGIS] extension +# from the repositories, at the indicated version. +# [PostGIS] http://postgis.net/ + +postgresql_postgis: no +postgresql_postgis_version: '2.1' + + +# If enabled, this will install the development headers. + +postgresql_dev_headers: no diff --git a/provision/roles/zenoamaro.postgresql/handlers/main.yml b/provision/roles/zenoamaro.postgresql/handlers/main.yml new file mode 100644 index 0000000..eadc7e2 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: restart postgresql + sudo: yes + service: name=postgresql state=restarted + +- name: reload postgresql + sudo: yes + service: name=postgresql state=reloaded \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/inventory b/provision/roles/zenoamaro.postgresql/inventory new file mode 100644 index 0000000..5c97f17 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/inventory @@ -0,0 +1,19 @@ +[boxed] +192.168.33.10 ansible_ssh_private_key_file=.vagrant/machines/boxed/virtualbox/private_key + +[test-ubuntu-precise] +192.168.33.20 ansible_ssh_private_key_file=.vagrant/machines/test-ubuntu-precise/virtualbox/private_key + +[test-ubuntu-trusty] +192.168.33.21 ansible_ssh_private_key_file=.vagrant/machines/test-ubuntu-trusty/virtualbox/private_key + +[test:children] +test-ubuntu-precise +test-ubuntu-trusty + +[vagrant:children] +test +boxed + +[vagrant:vars] +ansible_ssh_user=vagrant \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/main.yml b/provision/roles/zenoamaro.postgresql/main.yml new file mode 100644 index 0000000..031041d --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/main.yml @@ -0,0 +1,19 @@ +--- + +# Quick-provisioning playbook +# --------------------------- + +# A Simple, straight playbook for quick remote installations. +# You will be asked which hosts to provision before-hand. + + +- name: 'PostgreSQL' + + vars_prompt: + selected_hosts: Specify the hosts to provision + + hosts: "{{selected_hosts}}" + + roles: + - '.' # The current directory itself is the role + diff --git a/provision/roles/zenoamaro.postgresql/meta/.galaxy_install_info b/provision/roles/zenoamaro.postgresql/meta/.galaxy_install_info new file mode 100644 index 0000000..9bc6a43 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/meta/.galaxy_install_info @@ -0,0 +1 @@ +{install_date: 'Thu Feb 25 15:47:50 2016', version: v0.1.2} diff --git a/provision/roles/zenoamaro.postgresql/meta/main.yml b/provision/roles/zenoamaro.postgresql/meta/main.yml new file mode 100644 index 0000000..7643407 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/meta/main.yml @@ -0,0 +1,21 @@ +--- + +galaxy_info: + author: zenoamaro + description: A role for installing and configuring PostgreSQL + version: 0.1.2 + license: MIT + min_ansible_version: 1.4 + + platforms: + - name: Debian + - name: Ubuntu + versions: + - precise + - trusty + + categories: + - database + - database:sql + +dependencies: [] diff --git a/provision/roles/zenoamaro.postgresql/tasks/configure.yml b/provision/roles/zenoamaro.postgresql/tasks/configure.yml new file mode 100644 index 0000000..4db7047 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/tasks/configure.yml @@ -0,0 +1,55 @@ +--- + +- name: Create the necessary directories + sudo: yes + file: + dest: "{{item}}" + state: directory + owner: "{{postgresql_admin_user}}" + group: "{{postgresql_admin_group}}" + with_items: + - "{{postgresql_conf_directory}}" + - "{{postgresql_data_directory}}" + - "{{postgresql_runtime_directory}}" + - "{{postgresql_log_directory}}" + tags: + - postgresql + - db + - conf + +- name: Configure PostgreSQL + sudo: yes + template: + src: "{{item}}" + dest: "{{postgresql_conf_directory}}/{{item}}" + with_items: + - postgresql.conf + - pg_ctl.conf + - environment + notify: restart postgresql + tags: + - postgresql + - db + - conf + +- name: Configure PostgreSQL (authentication) + sudo: yes + template: + src: pg_hba.conf + dest: "{{postgresql_hba_file}}" + notify: restart postgresql + tags: + - postgresql + - db + - conf + +- name: Configure PostgreSQL (ident) + sudo: yes + template: + src: pg_ident.conf + dest: "{{postgresql_ident_file}}" + notify: restart postgresql + tags: + - postgresql + - db + - conf diff --git a/provision/roles/zenoamaro.postgresql/tasks/extensions.yml b/provision/roles/zenoamaro.postgresql/tasks/extensions.yml new file mode 100644 index 0000000..bc5aa86 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/tasks/extensions.yml @@ -0,0 +1,49 @@ +--- + + +# Development headers and libraries +# --------------------------------- + +- name: Install development headers + when: postgresql_dev_headers == True + sudo: yes + apt: + name: libpq-dev + tags: + - postgresql + - db + - deps + - dev + + +# Contributed extensions +# ---------------------- + +- name: Install PostgreSQL contribs + when: postgresql_contrib + sudo: yes + apt: + name: "postgresql-contrib-{{postgresql_version}}" + notify: restart postgresql + tags: + - postgresql + - db + - deps + + +# PostGIS +# ------- + +- name: Add postgis extensions + when: postgresql_postgis + sudo: yes + apt: + name: "{{item}}" + with_items: + - "postgresql-{{postgresql_version}}-postgis-{{postgresql_postgis_version}}" + - libgeos-c1 + notify: restart postgresql + tags: + - postgresql + - db + - deps diff --git a/provision/roles/zenoamaro.postgresql/tasks/install.yml b/provision/roles/zenoamaro.postgresql/tasks/install.yml new file mode 100644 index 0000000..b04a561 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/tasks/install.yml @@ -0,0 +1,51 @@ +--- + +# Official PostgreSQL [repository] for debian-based distributions +# [repository]: http://www.postgresql.org/download/ + +- name: Adding APT repository key + when: ansible_os_family == 'Debian' + sudo: yes + apt_key: + id: ACCC4CF8 + url: https://www.postgresql.org/media/keys/ACCC4CF8.asc + tags: + - postgresql + - db + - repo + +- name: Add PostgreSQL official APT repository + when: ansible_os_family == 'Debian' + sudo: yes + apt_repository: + repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main" + tags: + - postgresql + - db + - repo + +- name: Install PostgreSQL + when: ansible_os_family == 'Debian' + sudo: yes + apt: + name: "postgresql-{{postgresql_version}}" + state: present + update_cache: yes + cache_valid_time: 3600 + tags: + - postgresql + - db + - deps + +- name: Install dependencies for the Ansible module + when: ansible_os_family == 'Debian' + sudo: yes + apt: + name: "{{item}}" + state: latest + with_items: + - python-psycopg2 + tags: + - postgresql + - db + - deps diff --git a/provision/roles/zenoamaro.postgresql/tasks/main.yml b/provision/roles/zenoamaro.postgresql/tasks/main.yml new file mode 100644 index 0000000..0d839f4 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/tasks/main.yml @@ -0,0 +1,5 @@ +--- + +- include: install.yml +- include: extensions.yml +- include: configure.yml diff --git a/provision/roles/zenoamaro.postgresql/templates/environment b/provision/roles/zenoamaro.postgresql/templates/environment new file mode 100644 index 0000000..995a0c8 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/templates/environment @@ -0,0 +1,11 @@ +# environment variables for postmaster process +# This file has the same syntax as postgresql.conf: +# VARIABLE = simple_value +# VARIABLE2 = 'any value!' +# I. e. you need to enclose any value which does not only consist of letters, +# numbers, and '-', '_', '.' in single quotes. Shell commands are not +# evaluated. + +{% if postgresql_env %}{% for k,v in postgresql_env.items() %} +{{k}} = {{v}} +{% endfor %}{% endif %} \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/templates/pg_ctl.conf b/provision/roles/zenoamaro.postgresql/templates/pg_ctl.conf new file mode 100644 index 0000000..db8cb58 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/templates/pg_ctl.conf @@ -0,0 +1,5 @@ +# Automatic pg_ctl configuration +# This configuration file contains cluster specific options to be passed to +# pg_ctl(1). + +pg_ctl_options = '{{ postgresql_pg_ctl_options|join(' ')|replace('\'', '\\\'') }}' \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/templates/pg_hba.conf b/provision/roles/zenoamaro.postgresql/templates/pg_hba.conf new file mode 100644 index 0000000..f0a7d38 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/templates/pg_hba.conf @@ -0,0 +1,112 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: "local" is a Unix-domain +# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, +# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a +# plain TCP/IP socket. +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", +# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that +# "password" sends passwords in clear text; "md5" is preferred since +# it sends encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the postmaster receives +# a SIGHUP signal. If you edit the file on a running system, you have +# to SIGHUP the postmaster for the changes to take effect. You can +# use "pg_ctl reload" to do that. + +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + +# TYPE DATABASE USER ADDRESS METHOD + +{% for auth in postgresql_authentication %} +{{auth.type}} {% if 'database' not in auth %} +samerole{% elif auth.database is string %} +{{auth.database}}{% elif auth.database is sequence %} +{{auth.database|join(',')}}{% endif %} {{auth.user}} {{auth.address|default('')}} {{auth.method}} {% if 'options' in auth %} {% for k,v in auth.options.items() %} +{{k}}={{v}} {% endfor %}{% endif %} + +{% endfor %} + + +# DO NOT DISABLE! +# If you change this first entry you will need to make sure that the +# database superuser can access the database using some other method. +# Noninteractive access to all databases is required during automatic +# maintenance (custom daily cronjobs, replication, and similar tasks). +# +# Database administrative login by Unix domain socket + +# TYPE DATABASE USER ADDRESS METHOD + +local all {{postgresql_admin_user|default('postgres')}} peer + +# "local" is for Unix domain socket connections only +local all all peer + +# IPv4 local connections: +host all all 127.0.0.1/32 md5 + +# IPv6 local connections: +host all all ::1/128 md5 + +# Allow replication connections from localhost, by a user with the +# replication privilege. +#local replication postgres peer +#host replication postgres 127.0.0.1/32 md5 +#host replication postgres ::1/128 md5 \ No newline at end of file diff --git a/provision/roles/zenoamaro.postgresql/templates/pg_ident.conf b/provision/roles/zenoamaro.postgresql/templates/pg_ident.conf new file mode 100644 index 0000000..a9007ba --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/templates/pg_ident.conf @@ -0,0 +1,46 @@ +# PostgreSQL User Name Maps +# ========================= +# +# Refer to the PostgreSQL documentation, chapter "Client +# Authentication" for a complete description. A short synopsis +# follows. +# +# This file controls PostgreSQL user name mapping. It maps external +# user names to their corresponding PostgreSQL user names. Records +# are of the form: +# +# MAPNAME SYSTEM-USERNAME PG-USERNAME +# +# (The uppercase quantities must be replaced by actual values.) +# +# MAPNAME is the (otherwise freely chosen) map name that was used in +# pg_hba.conf. SYSTEM-USERNAME is the detected user name of the +# client. PG-USERNAME is the requested PostgreSQL user name. The +# existence of a record specifies that SYSTEM-USERNAME may connect as +# PG-USERNAME. +# +# If SYSTEM-USERNAME starts with a slash (/), it will be treated as a +# regular expression. Optionally this can contain a capture (a +# parenthesized subexpression). The substring matching the capture +# will be substituted for \1 (backslash-one) if present in +# PG-USERNAME. +# +# Multiple maps may be specified in this file and used by pg_hba.conf. +# +# No map names are defined in the default configuration. If all +# system user names and PostgreSQL user names are the same, you don't +# need anything in this file. +# +# This file is read on server startup and when the postmaster receives +# a SIGHUP signal. If you edit the file on a running system, you have +# to SIGHUP the postmaster for the changes to take effect. You can +# use "pg_ctl reload" to do that. + +# Put your actual configuration here +# ---------------------------------- + +# MAPNAME SYSTEM-USERNAME PG-USERNAME + +{% for mapping in postgresql_user_map %} +{{mapping.name}} {{mapping.user}} {{mapping.pg_user}} +{% endfor %} diff --git a/provision/roles/zenoamaro.postgresql/templates/postgresql.conf b/provision/roles/zenoamaro.postgresql/templates/postgresql.conf new file mode 100644 index 0000000..67335e5 --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/templates/postgresql.conf @@ -0,0 +1,530 @@ +# Memory units: kB = kilobytes Time units: ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# h = hours +# d = days + + +# File locations +# -------------- + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +# use data in another directory (change requires restart) +data_directory = '{{postgresql_data_directory}}' + +# host-based authentication file (change requires restart) +hba_file = '{{postgresql_hba_file}}' + +# ident configuration file (change requires restart) +ident_file = '{{postgresql_ident_file}}' + +# If external_pid_file is not explicitly set, no extra PID file is written. +# write an extra PID file (change requires restart) +external_pid_file = '{{postgresql_external_pid_file}}' + + +# Connections +# ----------- + +# What IP address(es) to listen on; comma-separated list of addresses. +listen_addresses = '{{postgresql_listen_addresses|join(', ')}}' +port = {{postgresql_port}} + +# Note: Increasing max_connections costs ~400 bytes of shared memory per +# connection slot, plus lock space (see max_locks_per_transaction). +max_connections = {{postgresql_max_connections}} +superuser_reserved_connections = {{postgresql_superuser_reserved_connections}} + +unix_socket_directories = '{{postgresql_unix_socket_directories|join(',')}}' # comma-separated list of directories +unix_socket_group = '{{postgresql_unix_socket_group}}' +unix_socket_permissions = {{postgresql_unix_socket_permissions}} # begin with 0 to use octal notation + +bonjour = {{'on' if postgresql_bonjour else 'off'}} # advertise server via Bonjour +bonjour_name = '{{postgresql_bonjour_name}}' # defaults to the computer name + + +# Security and Authentication +# --------------------------- + +authentication_timeout = {{postgresql_authentication_timeout}} +ssl = {{'on' if postgresql_ssl else 'off'}} +ssl_ciphers = '{{postgresql_ssl_ciphers|join(':')}}' +ssl_renegotiation_limit = {{postgresql_ssl_renegotiation_limit}} +ssl_cert_file = '{{postgresql_ssl_cert_file}}' +ssl_key_file = '{{postgresql_ssl_key_file}}' +ssl_ca_file = '{{postgresql_ssl_ca_file}}' +ssl_crl_file = '{{postgresql_ssl_crl_file}}' +password_encryption = {{'on' if postgresql_password_encryption else 'off'}} +db_user_namespace = {{'on' if postgresql_db_user_namespace else 'off'}} + +# Kerberos and GSSAPI +krb_server_keyfile = '{{postgresql_krb_server_keyfile}}' +krb_caseins_users = {{'on' if postgresql_db_user_namespace else 'off'}} + +# TCP Keepalives, 0 selects the system default +tcp_keepalives_idle = {{postgresql_tcp_keepalives_idle}} +tcp_keepalives_interval = {{postgresql_tcp_keepalives_interval}} +tcp_keepalives_count = {{postgresql_tcp_keepalives_count}} + + +# Memory +# ------ + +shared_buffers = {{postgresql_shared_buffers}} +temp_buffers = {{postgresql_temp_buffers}} + +# Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory +# per transaction slot, plus lock space (see max_locks_per_transaction). +# It is not advisable to set max_prepared_transactions nonzero unless you +# actively intend to use prepared transactions. +max_prepared_transactions = {{postgresql_max_prepared_transactions}} # 0 disables the feature + +work_mem = {{postgresql_work_mem}} # min 64kB +maintenance_work_mem = {{postgresql_maintenance_work_mem}} # min 1MB +max_stack_depth = {{postgresql_max_stack_depth}} # min 100kB + +# Disk +# ---- + +# limits per-session temp file space in kB, or -1 for no limit +temp_file_limit = {{postgresql_temp_file_limit}} + +# Kernel Resource Usage +# --------------------- + +max_files_per_process = {{postgresql_max_files_per_process}} # min 25 +shared_preload_libraries = '{{postgresql_shared_preload_libraries|join(',')}}' + +# Cost-Based Vacuum Delay +# ----------------------- + +vacuum_cost_delay = {{postgresql_vacuum_cost_delay}} # 0-100 milliseconds +vacuum_cost_page_hit = {{postgresql_vacuum_cost_page_hit}} # 0-10000 credits +vacuum_cost_page_miss = {{postgresql_vacuum_cost_page_miss}} # 0-10000 credits +vacuum_cost_page_dirty = {{postgresql_vacuum_cost_page_dirty}} # 0-10000 credits +vacuum_cost_limit = {{postgresql_vacuum_cost_limit}} # 1-10000 credits + +# Background Writer +# ----------------- + +bgwriter_delay = {{postgresql_bgwriter_delay}} # 10-10000ms between rounds +bgwriter_lru_maxpages = {{postgresql_bgwriter_lru_maxpages}} # 0-1000 max buffers written/round +bgwriter_lru_multiplier = {{postgresql_bgwriter_lru_multiplier}} # 0-10.0 multipler on buffers scanned/round + +# Asynchronous Behavior +# --------------------- + +effective_io_concurrency = {{postgresql_effective_io_concurrency}} # 1-1000; 0 disables prefetching + + +# Write Ahead Log +# --------------- + +wal_level = {{postgresql_wal_level}} # minimal, archive, or hot_standby +fsync = {{'on' if postgresql_fsync else 'off'}} # turns forced synchronization on or off + +# synchronization levels: +# - off +# - local +# - remote_write +# - on +{% if postgresql_synchronous_commit is string %} +synchronous_commit = {{postgresql_synchronous_commit}} +{% else %} +synchronous_commit = {{'on' if postgresql_synchronous_commit else 'off'}} +{% endif %} + +# The default is the first option supported by the operating system: +# - open_datasync +# - fdatasync (default on Linux) +# - fsync +# - fsync_writethrough +# - open_sync +wal_sync_method = {{postgresql_wal_sync_method}} + +# Recover from partial page writes +full_page_writes = {{'on' if postgresql_full_page_writes else 'off'}} + +wal_buffers = {{postgresql_wal_buffers}} # min 32kB, -1 sets based on shared_buffers +wal_writer_delay = {{postgresql_wal_writer_delay}} # 1-10000 milliseconds +commit_delay = {{postgresql_commit_delay}} # range 0-100000, in microseconds +commit_siblings = {{postgresql_commit_siblings}} # range 1-1000 + +checkpoint_segments = {{postgresql_checkpoint_segments}} # in logfile segments, min 1, 16MB each +checkpoint_timeout = {{postgresql_checkpoint_timeout}} # range 30s-1h +checkpoint_completion_target = {{postgresql_checkpoint_completion_target}} # checkpoint target duration, 0.0 - 1.0 +checkpoint_warning = {{postgresql_checkpoint_warning}} # 0 disables + +archive_mode = {{'on' if postgresql_archive_mode else 'off'}} # allows archiving to be done + +# Command to use to archive a logfile segment. +# Placeholders: %p = path of file to archive +# %f = file name only +# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +archive_command = '{{postgresql_archive_command}}' + +# force a logfile segment switch after this number of seconds +archive_timeout = {{postgresql_archive_timeout}} # 0 disables + + +# Replication +# ----------- + +# Set these on the master and on any standby that will send replication data. + +max_wal_senders = {{postgresql_max_wal_senders}} # max number of walsender processes +wal_keep_segments = {{postgresql_wal_keep_segments}} # in logfile segments, 16MB each; 0 disables +wal_sender_timeout = {{postgresql_wal_sender_timeout}} # in milliseconds; 0 disables + +# Replication (masters) +# --------------------- + +# These settings are ignored on a standby server. + +# Standby servers that provide sync rep. +# Comma-separated list of application_name from standby(s) +synchronous_standby_names = '{{postgresql_synchronous_standby_names|join(',')}}' # '*' means 'all' + +# Number of xacts by which cleanup is delayed +vacuum_defer_cleanup_age = {{postgresql_vacuum_defer_cleanup_age}} + +# Replication (standbys) +# ---------------------- + +# These settings are ignored on a master server. + +# "on" allows queries during recovery +hot_standby = {{'on' if postgresql_hot_standby else 'off'}} +# max delay before canceling queries when reading WAL from archive +max_standby_archive_delay = {{postgresql_max_standby_archive_delay}} # -1 allows indefinite delay +# max delay before canceling queries when reading streaming WAL; +max_standby_streaming_delay = {{postgresql_max_standby_streaming_delay}} # -1 allows indefinite delay +# send replies at least this often +wal_receiver_status_interval = {{postgresql_wal_receiver_status_interval}} # 0 disables +# send info from standby to prevent query conflicts +hot_standby_feedback = {{'on' if postgresql_hot_standby_feedback or 'off'}} +#time that receiver waits for communication from master in milliseconds +wal_receiver_timeout = {{postgresql_wal_receiver_timeout}} + + +# Query Tuning (Planner) +# ---------------------- + +enable_bitmapscan = {{'on' if postgresql_enable_bitmapscan else 'off'}} +enable_hashagg = {{'on' if postgresql_enable_hashagg else 'off'}} +enable_hashjoin = {{'on' if postgresql_enable_hashjoin else 'off'}} +enable_indexscan = {{'on' if postgresql_enable_indexscan else 'off'}} +enable_indexonlyscan = {{'on' if postgresql_enable_indexonlyscan else 'off'}} +enable_material = {{'on' if postgresql_enable_material else 'off'}} +enable_mergejoin = {{'on' if postgresql_enable_mergejoin else 'off'}} +enable_nestloop = {{'on' if postgresql_enable_nestloop else 'off'}} +enable_seqscan = {{'on' if postgresql_enable_seqscan else 'off'}} +enable_sort = {{'on' if postgresql_enable_sort else 'off'}} +enable_tidscan = {{'on' if postgresql_enable_tidscan else 'off'}} + +seq_page_cost = {{postgresql_seq_page_cost}} # measured on an arbitrary scale +random_page_cost = {{postgresql_random_page_cost}} # same scale as above +cpu_tuple_cost = {{postgresql_cpu_tuple_cost}} # same scale as above +cpu_index_tuple_cost = {{postgresql_cpu_index_tuple_cost}} # same scale as above +cpu_operator_cost = {{postgresql_cpu_operator_cost}} # same scale as above +effective_cache_size = {{postgresql_effective_cache_size}} + +# Query Tuning (Genetic Query Optimizer) +# -------------------------------------- + +geqo = {{'on' if postgresql_enable_tidscan else 'off'}} +geqo_threshold = {{postgresql_geqo_threshold}} +geqo_effort = {{postgresql_geqo_effort}} # range 1-10 +geqo_pool_size = {{postgresql_geqo_pool_size}} # selects default based on effort +geqo_generations = {{postgresql_geqo_generations}} # selects default based on effort +geqo_selection_bias = {{postgresql_geqo_selection_bias}} # range 1.5-2.0 +geqo_seed = {{postgresql_geqo_seed}} # range 0.0-1.0 + +# Query Tuning (Other Planner Options) +# ------------------------------------ + +default_statistics_target = {{postgresql_default_statistics_target}} # range 1-10000 +constraint_exclusion = {{postgresql_constraint_exclusion}} # on, off, or partition +cursor_tuple_fraction = {{postgresql_cursor_tuple_fraction}} # range 0.0-1.0 +from_collapse_limit = {{postgresql_from_collapse_limit}} +join_collapse_limit = {{postgresql_join_collapse_limit}} # 1 disables collapsing of explicit JOIN clauses + + +# Error Reporting And Logging +# --------------------------- + +# Valid values are combinations of stderr, csvlog, syslog, and eventlog. +# depending on platform. Csvlog requires logging_collector to be on. +log_destination = '{{postgresql_log_destination}}' + +# Enable capturing of stderr and csvlog into log files. +# Required to be on for csvlogs. +logging_collector = {{'on' if postgresql_logging_collector else 'off'}} + +# These are only used if logging_collector is on: + +# Directory where log files are written, can be absolute or relative to PGDATA +log_directory = '{{postgresql_log_directory}}' +# Log file name pattern, can include strftime() escapes +log_filename = '{{postgresql_log_filename}}' +log_file_mode = {{postgresql_log_file_mode}} # begin with 0 to use octal notation +# If on, an existing log file with the same name as the new log file will be +# truncated rather than appended to. But such truncation only occurs on +# time-driven rotation, not on restarts or size-driven rotation. Default is +# off, meaning append to existing files in all cases. +log_truncate_on_rotation = {{'on' if postgresql_log_truncate_on_rotation else 'off'}} +# Automatic rotation of logfiles will happen after that time. +log_rotation_age = {{postgresql_log_rotation_age}} # 0 disables. +# Automatic rotation of logfiles will happen after that much log output. +log_rotation_size = {{postgresql_log_rotation_size}} # 0 disables. + +# These are relevant when logging to syslog: +syslog_facility = '{{postgresql_syslog_facility}}' +syslog_ident = '{{postgresql_syslog_ident}}' + +# This is only relevant when logging to eventlog (win32): +event_source = '{{postgresql_event_source}}' + +# Values in order of decreasing detail: +# - debug5 +# - debug4 +# - debug3 +# - debug2 +# - debug1 +# - log +# - notice +# - warning +# - error +client_min_messages = {{postgresql_client_min_messages}} + +# Values in order of decreasing detail: +# - debug5 +# - debug4 +# - debug3 +# - debug2 +# - debug1 +# - info +# - notice +# - warning +# - error +# - log +# - fatal +# - panic +log_min_messages = {{postgresql_log_min_messages}} + +# Values in order of decreasing detail: +# - debug5 +# - debug4 +# - debug3 +# - debug2 +# - debug1 +# - info +# - notice +# - warning +# - error +# - log +# - fatal +# - panic (effectively off) +log_min_error_statement = {{postgresql_log_min_error_statement}} + +# -1 is disabled, 0 logs all statements and their durations, > 0 logs only +# statements running at least this number of milliseconds +log_min_duration_statement = {{postgresql_log_min_duration_statement}} + +debug_print_parse = {{'on' if postgresql_debug_print_parse else 'off'}} +debug_print_rewritten = {{'on' if postgresql_debug_print_rewritten else 'off'}} +debug_print_plan = {{'on' if postgresql_debug_print_plan else 'off'}} +debug_pretty_print = {{'on' if postgresql_debug_pretty_print else 'off'}} +log_checkpoints = {{'on' if postgresql_log_checkpoints else 'off'}} +log_connections = {{'on' if postgresql_log_connections else 'off'}} +log_disconnections = {{'on' if postgresql_log_disconnections else 'off'}} +log_duration = {{'on' if postgresql_log_duration else 'off'}} +log_error_verbosity = {{postgresql_log_error_verbosity}} # terse, default, or verbose messages +log_hostname = {{'on' if postgresql_log_duration else 'off'}} + +# special values: +# %a = application name +# %u = user name +# %d = database name +# %r = remote host and port +# %h = remote host +# %p = process ID +# %t = timestamp without milliseconds +# %m = timestamp with milliseconds +# %i = command tag +# %e = SQL state +# %c = session ID +# %l = session line number +# %s = session start timestamp +# %v = virtual transaction ID +# %x = transaction ID (0 if none) +# %q = stop here in non-session +# processes +# %% = '%' +log_line_prefix = '{{postgresql_log_line_prefix}}' + +# log lock waits >= deadlock_timeout +log_lock_waits = {{'on' if postgresql_log_lock_waits else 'off'}} +log_statement = '{{postgresql_log_statement}}' # none, ddl, mod, all +# log temporary files equal or larger than the specified size in kilobytes +log_temp_files = {{postgresql_log_temp_files}} # -1 disables, 0 logs all temp files +log_timezone = '{{postgresql_log_timezone}}' + + +# Runtime statistics +# ------------------ + +track_activities = {{'on' if postgresql_track_activities else 'off'}} +track_counts = {{'on' if postgresql_track_counts else 'off'}} +track_io_timing = {{'on' if postgresql_track_io_timing else 'off'}} +track_functions = {{postgresql_track_functions}} # none, pl, all +track_activity_query_size = {{postgresql_track_activity_query_size}} +update_process_title = {{'on' if postgresql_update_process_title else 'off'}} +stats_temp_directory = '{{postgresql_stats_temp_directory}}' + +log_parser_stats = {{'on' if postgresql_log_parser_stats else 'off'}} +log_planner_stats = {{'on' if postgresql_log_planner_stats else 'off'}} +log_executor_stats = {{'on' if postgresql_log_executor_stats else 'off'}} +log_statement_stats = {{'on' if postgresql_log_statement_stats else 'off'}} + + +# Autovacuum Parameters +# --------------------- + +# Enable autovacuum subprocess? 'on' requires track_counts to also be on. +autovacuum = {{'on' if postgresql_autovacuum else 'off'}} +# -1 disables, 0 logs all actions and their durations, > 0 logs only +# actions running at least this number of milliseconds. +log_autovacuum_min_duration = {{postgresql_log_autovacuum_min_duration}} +# max number of autovacuum subprocesses +autovacuum_max_workers = {{postgresql_autovacuum_max_workers}} +# time between autovacuum runs +autovacuum_naptime = {{postgresql_autovacuum_naptime}} +# min number of row updates before vacuum +autovacuum_vacuum_threshold = {{postgresql_autovacuum_vacuum_threshold}} +# min number of row updates before analyze +autovacuum_analyze_threshold = {{postgresql_autovacuum_analyze_threshold}} +# fraction of table size before vacuum +autovacuum_vacuum_scale_factor = {{postgresql_autovacuum_vacuum_scale_factor}} +# fraction of table size before analyze +autovacuum_analyze_scale_factor = {{postgresql_autovacuum_analyze_scale_factor}} +# maximum XID age before forced vacuum +autovacuum_freeze_max_age = {{postgresql_autovacuum_freeze_max_age}} +# default vacuum cost delay for autovacuum, in milliseconds +autovacuum_vacuum_cost_delay = {{postgresql_autovacuum_vacuum_cost_delay}} # -1 means use vacuum_cost_delay +# default vacuum cost limit for autovacuum +autovacuum_vacuum_cost_limit = {{postgresql_autovacuum_vacuum_cost_limit}} # -1 means use vacuum_cost_limit + + +# Client Connection Defaults +# -------------------------- + +search_path = '{{postgresql_search_path|join(',')}}' # schema names +default_tablespace = '{{postgresql_default_tablespace}}' # '' uses the default +temp_tablespaces = '{{postgresql_temp_tablespaces|join(',')}}' # '' uses only default tablespace + +check_function_bodies = {{'on' if postgresql_check_function_bodies else 'off'}} +default_transaction_isolation = '{{postgresql_default_transaction_isolation}}' +default_transaction_read_only = {{'on' if postgresql_default_transaction_read_only else 'off'}} +default_transaction_deferrable = {{'on' if postgresql_default_transaction_deferrable else 'off'}} +session_replication_role = '{{postgresql_session_replication_role}}' + +statement_timeout = {{postgresql_statement_timeout}} # in milliseconds, 0 is disabled +lock_timeout = {{postgresql_lock_timeout}} # in milliseconds, 0 is disabled +vacuum_freeze_min_age = {{postgresql_vacuum_freeze_min_age}} +vacuum_freeze_table_age = {{postgresql_vacuum_freeze_table_age}} + +bytea_output = '{{postgresql_bytea_output}}' # hex, escape +xmlbinary = '{{postgresql_xmlbinary}}' +xmloption = '{{postgresql_xmloption}}' + +datestyle = '{{postgresql_datestyle|join(',')}}' +intervalstyle = '{{postgresql_intervalstyle}}' +timezone = '{{postgresql_timezone}}' + +# Select the set of available time zone abbreviations. Currently, there are: +# - Default +# - Australia +# - India +# You can create your own file in `share/timezonesets/`. +timezone_abbreviations = '{{postgresql_timezone_abbreviations}}' + +extra_float_digits = {{postgresql_extra_float_digits}} # min -15, max 3 +client_encoding = {{postgresql_client_encoding}} # 'sql_ascii' actually defaults to database encoding + +# These settings are initialized by initdb, but they can be changed. + +# locale for system error message strings +lc_messages = '{{postgresql_lc_messages}}' +# locale for monetary formatting +lc_monetary = '{{postgresql_lc_monetary}}' +# locale for number formatting +lc_numeric = '{{postgresql_lc_numeric}}' +# locale for time formatting +lc_time = '{{postgresql_lc_time}}' + +# default configuration for text search +default_text_search_config = '{{postgresql_default_text_search_config}}' + +dynamic_library_path = '{{postgresql_dynamic_library_path}}' +local_preload_libraries = '{{postgresql_local_preload_libraries|join(',')}}' + + +# Lock Management +# --------------- + +deadlock_timeout = {{postgresql_deadlock_timeout}} +max_locks_per_transaction = {{postgresql_max_locks_per_transaction}} # min 10 + +# Note: Each lock table slot uses ~270 bytes of shared memory, and there are +# max_locks_per_transaction * (max_connections + max_prepared_transactions) +# lock table slots. +max_pred_locks_per_transaction = {{postgresql_max_pred_locks_per_transaction}} # min 10 + + +# Version/platform Compatibility +# ------------------------------ + +array_nulls = {{'on' if postgresql_array_nulls else 'off'}} +backslash_quote = {{postgresql_backslash_quote}} # on, off, or safe_encoding +default_with_oids = {{'on' if postgresql_default_with_oids else 'off'}} +escape_string_warning = {{'on' if postgresql_escape_string_warning else 'off'}} +lo_compat_privileges = {{'on' if postgresql_lo_compat_privileges else 'off'}} +quote_all_identifiers = {{'on' if postgresql_quote_all_identifiers else 'off'}} +sql_inheritance = {{'on' if postgresql_sql_inheritance else 'off'}} +standard_conforming_strings = {{'on' if postgresql_standard_conforming_strings else 'off'}} +synchronize_seqscans = {{'on' if postgresql_synchronize_seqscans else 'off'}} +transform_null_equals = {{'on' if postgresql_transform_null_equals else 'off'}} + + +# Error Handling +# -------------- + +# Terminate session on any error? +exit_on_error = {{'on' if postgresql_exit_on_error else 'off'}} +# Reinitialize after backend crash? +restart_after_crash = {{'on' if postgresql_restart_after_crash else 'off'}} + + +# Config File Includes +# -------------------- + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. + +# include files ending in '.conf' from directory 'conf.d' +#include_dir = 'conf.d' + +# include file only if it exists +#include_if_exists = 'exists.conf' + +# include file +#include = 'special.conf' + + +# CUSTOMIZED OPTIONS +# ------------------ + +# Add settings for extensions here diff --git a/provision/roles/zenoamaro.postgresql/test.yml b/provision/roles/zenoamaro.postgresql/test.yml new file mode 100644 index 0000000..f48ad4f --- /dev/null +++ b/provision/roles/zenoamaro.postgresql/test.yml @@ -0,0 +1,24 @@ +# Integration testing playbook +# ---------------------------- + +# A playbook for testing and integration. + +# It will provision the `test` hosts in the inventory, +# which will, by default, specify the provided vagrant VM. + +# This playbook should aim to test the most extensive +# or comprehensive configuration possible for your role. + + +- name: 'Role integration tests' + + hosts: test + + vars: + postgresql_dev_headers: yes + postgresql_contrib: yes + postgresql_postgis: yes + + roles: + - '.' # The current directory itself is the role + diff --git a/provision/site.retry b/provision/site.retry new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/provision/site.retry @@ -0,0 +1 @@ +default diff --git a/provision/site.yml b/provision/site.yml new file mode 100644 index 0000000..c3806eb --- /dev/null +++ b/provision/site.yml @@ -0,0 +1,18 @@ +--- +- name: Base tasks + hosts: [development, staging, production] + remote_user: root + roles: + - common + - zenoamaro.postgresql + - python + - database + - app + +- name: Deployment tasks + hosts: [production] + remote_user: root + roles: + - deploy-code + - supervisor + - nginx diff --git a/provision/templates/humans.txt b/provision/templates/humans.txt new file mode 100755 index 0000000..ee0afa2 --- /dev/null +++ b/provision/templates/humans.txt @@ -0,0 +1,18 @@ +# humanstxt.org/ +# The humans responsible & technology colophon + +# TEAM + Electric Umbrella + Drew Larson -- Lead -- @drwlrsn + +# THANKS + + + +# TECHNOLOGY COLOPHON + + HTML5, CSS3 + jQuery, Modernizr, + Django, Wagtail, + Satchless, SASS, + Bourbon diff --git a/provision/templates/pg_hba.conf b/provision/templates/pg_hba.conf new file mode 100644 index 0000000..ed12eff --- /dev/null +++ b/provision/templates/pg_hba.conf @@ -0,0 +1,3 @@ +local all postgres peer +local all vagrant peer +local all {{ db_user }} peer diff --git a/requirements/base.txt b/requirements/base.txt new file mode 100644 index 0000000..bf263ed --- /dev/null +++ b/requirements/base.txt @@ -0,0 +1,8 @@ +Django==1.9.4 +pytz==2015.7 +django-widget-tweaks==1.4.1 +psycopg2==2.6.1 +celery[redis]==3.1.23 +django-celery==3.1.17 +opbeat==3.3 +django-tz-detect==0.2.6 diff --git a/requirements/development.txt b/requirements/development.txt new file mode 100644 index 0000000..ed79a47 --- /dev/null +++ b/requirements/development.txt @@ -0,0 +1,4 @@ +-r base.txt +-r testing.txt +django-debug-toolbar +PyYAML diff --git a/requirements/production.txt b/requirements/production.txt new file mode 100644 index 0000000..a945c48 --- /dev/null +++ b/requirements/production.txt @@ -0,0 +1,2 @@ +-r base.txt +gunicorn==19.4.5 diff --git a/requirements/staging.txt b/requirements/staging.txt new file mode 100644 index 0000000..d7f1e2f --- /dev/null +++ b/requirements/staging.txt @@ -0,0 +1 @@ +-r production.txt diff --git a/requirements/testing.txt b/requirements/testing.txt new file mode 100644 index 0000000..8acfd72 --- /dev/null +++ b/requirements/testing.txt @@ -0,0 +1,2 @@ +coverage +mock \ No newline at end of file