Skip to content

Instantly share code, notes, and snippets.

@njones11
Created May 23, 2014 14:43
Show Gist options
  • Save njones11/22abd265093cd54da222 to your computer and use it in GitHub Desktop.
Save njones11/22abd265093cd54da222 to your computer and use it in GitHub Desktop.
## Copyright (c) 2014 Elysium Digital LLC
##
## 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.
##
################################################################################
##
## Django Deployment Salt State
##
## All of the following variables are read from the Salt Pillar
##
## Application Specific Variables
##
## app -- the name of the app / git repo (assumed to be the same)
## django_app_name -- The root of the PYTHONPATH
## wsgi_path -- relative path to wsgi.py from /home/ instance / app /
## static_files -- relative path to the static file dir from /home/ instance / app /
##
## Instance Specific Variables
##
## instance -- the name of this instance; creates a system user with same name
## website_name -- name of the domain for the apache conf
## settings -- settings to be passed to manage.py --settings=
## instance_admins -- which users are allowed to sudo su instance
## redirects -- Apache mod_rewrite redirects that should be added.
## rev -- The git target
## repo_path -- The repo path in gitolite
## requirements -- Path to requirements file from root
## syncdb -- run syncdb
## south -- run south migration
## secret_key -- Will be set in the WSGI processes environment
## no_auth_internal -- Don't use any kind of apache auth if coming from an internal IP.
{% from "smartos/macros.sls" import allow_cron %}
{% set dp = pillar['django_pillar'] %}
{% set ap = pillar['apache_pillar'] %}
include:
- generic.apache
- generic.postgresql
- generic.base
{% for app in dp['apps'] %}
{% if dp['apps'][app]['instances'] != None %}
{% for instance in dp['apps'][app]['instances'] %}
- generic.django.{{ instance }}
{% endfor %}
{% endif %}
{% endfor %}
extend:
service_httpd:
service:
- require:
{% for app in dp['apps'] %}
{% if dp['apps'][app]['instances'] != None %}
{% for instance in dp['apps'][app]['instances'] %}
- file: {{ ap['apache_conf_dir'] }}/conf.d/{{ instance }}.conf
{% endfor %}
{% endif %}
{% endfor %}
- watch:
{% for app in dp['apps'] %}
{% if dp['apps'][app]['instances'] != None %}
{% for instance in dp['apps'][app]['instances'] %}
- git: {{ instance }}_git
{% if dp['apps'][app]['instances'][instance]['compress'] %}
- cmd: {{ instance }}_compress
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% for app in dp['apps'] %}
{% set ad = dp['apps'][app] %} # app dict
{% if ad['instances'] != None %}
{% for instance in ad['instances'] %}
{% set id = ad['instances'][instance] %} # instance dict
{{ instance }}:
group:
- present
user.present:
- gid_from_name: True
- system: True
- fullname: {{ instance}} user
- home: /home/{{ instance }}
- shell: /bin/bash
- require:
- user: placeholder
{% if grains['osfullname'] == 'SmartOS' %}
{{ allow_cron(instance) }}
{% endif %}
{{ pillar['sudo_pillar']['sudoers_d'] }}/{{ instance }}:
file.managed:
- user: root
- group: root
- mode: 600
- template: jinja
- instance: {{ instance }}
- instance_admins: {{ id['instance_admins'] }}
- source: salt://generic/files/django/sudoers
/home/{{ instance }}:
file.directory:
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
- mode: 750
- require:
- pkg: apache_pkgs
- pkg: pip
- user: {{ instance }}
{{ instance}}_log_dir:
file.directory:
- name: /home/{{ instance }}/logs/
- user: {{ instance }}
- mode: 700
- require:
- file: /home/{{ instance }}
{{ instance}}_backup_root:
file.directory:
- name: /home/{{ instance }}/backups/
- user: {{ instance }}
- mode: 700
- require:
- file: /home/{{ instance }}
{{ instance}}_backup_dirs:
file.directory:
- names:
- /home/{{ instance }}/backups/hourly
- /home/{{ instance }}/backups/daily
- /home/{{ instance }}/backups/weekly
- /home/{{ instance }}/backups/monthly
- user: {{ instance }}
- mode: 700
- makedirs: True
- require:
- file: {{ instance }}_backup_root
{{ instance }}_backup_script:
file.managed:
- name: /home/{{ instance }}/backups/backup.py
- source: salt://generic/files/django/backup.py
- template: jinja
- remote_db: {{ id['remote_db'] }}
- db_user: {{ instance }}
- db_password: {{ id['db_password'] }}
{% if id['remote_db'] %}
- db_host: {{ id['db_host'] }}
{% else %}
- db_host: ''
{% endif %}
- user: {{ instance }}
- mode: 700
- require:
- file: {{ instance }}_backup_dirs
{% if id['backups'] %}
{{ instance }}_backup_cron:
cron.present:
- name: /home/{{ instance }}/backups/backup.py
- user: {{ instance }}
- minute: random
- require:
- file: {{ instance }}_backup_script
{% else %}
{{ instance }}_backup_cron_absent:
cron.absent:
- name: /home/{{ instance }}/backups/backup.py
- user: {{ instance }}
- require:
- file: {{ instance }}_backup_script
{{ instance }}_backup_cron_absent_root:
cron.absent:
- name: /home/{{ instance }}/backups/backup.py
- user: root
- require:
- file: {{ instance }}_backup_script
{% endif %}
/home/{{ instance }}/.ssh:
file.directory:
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
- mode: 700
- require:
- user: {{ instance }}
- group: {{ instance }}
- file: /home/{{ instance }}
/home/{{ instance }}/.ssh/id_rsa:
file.managed:
- source: salt://generic/files/ssh_keys/{{ app }}_read_only_id_rsa
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
- mode: 600
- require:
- file: /home/{{ instance }}/.ssh
/home/{{ instance }}/.ssh/id_rsa.pub:
file.managed:
- source: salt://generic/files/ssh_keys/{{ app }}_read_only_id_rsa.pub
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
- mode: 600
- require:
- file: /home/{{ instance }}/.ssh
/home/{{ instance }}/.git:
file.directory:
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
- mode: 700
- require:
- user: {{ instance }}
- group: {{ instance }}
- file: /home/{{ instance }}
{{ instance }}_ssh_key:
ssh_known_hosts:
- name: foo.bar.com
- present
- user: {{ instance }}
- fingerprint: 00:00:00:00:00:00:00:00:00:00
- require:
- file: /home/{{ instance }}/.ssh
{{ instance }}_git:
git.latest:
- name: ssh://[email protected]/{{ ad['repo_path'] }}
- target: /home/{{ instance }}/{{ app }}
- user: {{ instance }}
- rev: {{ id['rev'] }}
- force: True
- force_checkout: True
- require:
- file: /home/{{ instance }}/.ssh/id_rsa
- file: /home/{{ instance }}/.ssh/id_rsa.pub
- ssh_known_hosts: {{ instance }}_ssh_key
- pkg: git
/home/{{ instance }}/{{ app }}:
file.directory:
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
# - mode: 750 # Don't turn this on, git manages mode
- recurse:
- user
- group
- require:
- git: {{ instance }}_git
{{ instance }}_requirements_file:
file:
- name: /home/{{ instance }}/{{ app }}/{{ id['requirements'] }}
- exists
- require:
- git: {{ instance }}_git
/home/{{ instance }}/virtualenv:
file.directory:
- user: {{ instance }}
- group: {{ ap['apache_group'] }}
- mode: 750
- require:
- file: {{ instance }}_requirements_file
# Do not recurse! It will break everything!
# Virtualenv is symlinked to system python!
virtualenv.managed:
- requirements: /home/{{ instance }}/{{ app }}/{{ id['requirements'] }}
- runas: {{ instance }}
- no_chown: True
- system_site_packages: False
- cwd: /home/{{ instance }}/{{ app }}/
{% if ad['python3'] %}
- python: /opt/local/bin/python3.3
{% endif %}
- require:
- file: {{ instance }}_requirements_file
- pkg: pip
- pkg: virtualenv
{% if not id['remote_db'] %}
{{ instance }}_db:
postgres_database:
- name: {{ instance }}
- present
- runas: postgres
- owner: {{ instance }}
- require:
- service: postgresql
- file: pg_hba
- file: pg_ident
- file: postgresql_conf
- postgres_user: {{ instance }}_dbuser
{{ instance }}_dbuser:
postgres_user:
- name: {{ instance }}
- present
- password: {{ id['db_password'] }}
- runas: postgres
- require:
- service: postgresql
{% endif %}
{% if ad['syncdb'] and not id['no_db'] %}
{{ instance }}_syncdb:
cmd:
- name: >
su {{ instance }} -c "
source /home/{{ instance }}/virtualenv/bin/activate;
export DJANGO_SETTINGS_MODULE={{ id['settings'] }};
export PYTHONPATH=/home/{{ instance }}/{{ app }}/{{ ad['django_app_name'] }};
export SECRET_KEY={{ id['secret_key'] }};
django-admin.py syncdb --noinput;"
- run
- require:
{% if not id['remote_db'] %}
- postgres_database: {{ instance }}
- postgres_user: {{ instance }}
{% endif %}
- virtualenv: /home/{{ instance }}/virtualenv
- git: {{ instance }}_git
{% endif %}
{% if ad['south'] and not id['no_db'] %}
{{ instance }}_migrate:
cmd:
- name: >
su {{ instance }} -c "
source /home/{{ instance }}/virtualenv/bin/activate;
export DJANGO_SETTINGS_MODULE={{ id['settings'] }};
export PYTHONPATH=/home/{{ instance }}/{{ app }}/{{ ad['django_app_name'] }};
export SECRET_KEY={{ id['secret_key'] }};
django-admin.py migrate --noinput;"
- run
- require:
{% if not id['remote_db'] %}
- postgres_database: {{ instance }}
- postgres_user: {{ instance }}
{% endif %}
- virtualenv: /home/{{ instance }}/virtualenv
- git: {{ instance }}_git
- cmd: {{ instance }}_syncdb
{% endif %}
{% if ad['sphinx'] %}
{{ instance }}_sphinx:
cmd:
- name: >
su {{ instance }} -c "
source /home/{{ instance }}/virtualenv/bin/activate;
cd /home/{{ instance }}/{{ app }}/docs/;
make clean;
make html;"
- run
- require:
- virtualenv: /home/{{ instance }}/virtualenv
- git: {{ instance }}_git
{% endif %}
{% if ad['collectstatic'] %}
{{ instance }}_collectstatic:
cmd:
- name: >
su {{ instance }} -c "
source /home/{{ instance }}/virtualenv/bin/activate;
export DJANGO_SETTINGS_MODULE={{ id['settings'] }};
export PYTHONPATH=/home/{{ instance }}/{{ app }}/{{ ad['django_app_name'] }};
export SECRET_KEY={{ id['secret_key'] }};
django-admin.py collectstatic --noinput ;"
- run
- require:
{% if not id['remote_db'] %}
- postgres_database: {{ instance }}
- postgres_user: {{ instance }}
{% endif %}
- virtualenv: /home/{{ instance }}/virtualenv
- git: {{ instance }}_git
{% if ad['sphinx'] %}
- cmd: {{ instance }}_sphinx
{% endif %}
{% endif %}
{% if id['compress'] %}
{{ instance }}_compress:
cmd:
- name: >
su {{ instance }} -c "
source /home/{{ instance }}/virtualenv/bin/activate;
export DJANGO_SETTINGS_MODULE={{ id['settings'] }};
export PYTHONPATH=/home/{{ instance }}/{{ app }}/{{ ad['django_app_name'] }};
export SECRET_KEY={{ id['secret_key'] }};
django-admin.py compress;"
- run
- require:
- virtualenv: /home/{{ instance }}/virtualenv
- git: {{ instance }}_git
- cmd: {{ instance }}_collectstatic
{% endif %}
{% if id['auth_digest'] %}
{{instance}}_auth_user_file:
file.managed:
- name: {{ ap['apache_conf_dir'] }}/auth/{{ id['auth_user_file'] }}
- source: salt://generic/files/apache/httpd/auth/{{ id['auth_user_file'] }}
- user: {{ ap['apache_user'] }}
- group: {{ ap['apache_group'] }}
- mode: 600
{% endif %}
{{ instance }}_vhost_conf:
file.managed:
- name: {{ ap['apache_conf_dir'] }}/conf.d/{{ instance }}.conf
- template: jinja
##########################################
# App settings
##########################################
- app: {{ app }}
- django_app_name: {{ ad['django_app_name'] }}
- wsgi_path: {{ ad['wsgi_path'] }}
- static_files: {{ ad['static_files'] }}
##########################################
# Instance settings
##########################################
- instance: {{ instance }}
- server_name: {{ id['server_name'] }}
- mod_rewrite: {{ id['mod_rewrite'] }}
- redirects: {% if 'redirects' in id %}{{ id['redirects'] }}{% else %}{}{% endif %}
- domain_redirects: {% if 'domain_redirects' in id %}{{ id['domain_redirects'] }}{% else %}[]{% endif %}
- settings: {{ id['settings'] }}
- secret_key: {{ id['secret_key'] }}
- whitelist: {{ id['whitelist'] }}
- whitelist_ips: {{ id['whitelist_ips'] }}
##########################################
# Apache settings
##########################################
- ssl_certificate_file: {{ ap['ssl_certificate_file'] }}
- ssl_certificate_key_file: {{ ap['ssl_certificate_key_file'] }}
- ssl_certificate_chain_file: {% if ap['chain_file'] %}{{ ap['ssl_certificate_chain_file'] }}{% endif %}
- apache_conf_dir: {{ ap['apache_conf_dir'] }}
- hsts: {{ id['hsts'] }}
- processes: {{ id['processes'] }}
- threads: {{ id['threads'] }}
##########################################
# Auth digest settings
##########################################
- auth_digest: {{ id['auth_digest'] }}
- auth_name: {{ id['auth_name'] }}
- auth_user_file: {{ id['auth_user_file'] }}
##########################################
# Salt
##########################################
- source: salt://generic/files/apache/httpd/conf.d/django.conf
- user: {{ ap['apache_user'] }}
- group: {{ ap['apache_group'] }}
- mode: 600
- makedirs: True
- require:
- file: apache_dirs
- file: bad_files
- pkg: apache_pkgs
{% if id['auth_digest'] %}
- file: {{ instance }}_auth_user_file
{% endif %}
{% endfor %} # instance loop
{% endif %} # instance if
{% endfor %} # app loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment