Add initial Vagrant/Saltstack setup

This commit adds an initial Vagrant and Saltstack setup that reuses the
same configuration as that of the gva repository. The LDAP server itself
is not configured yet.
This commit is contained in:
Jan Dittberner 2016-01-29 23:26:57 +01:00
parent af8b9e974c
commit 6a8997e950
50 changed files with 1265 additions and 0 deletions

1
.gitignore vendored
View file

@ -40,3 +40,4 @@ Desktop.ini
.ropeproject
_build/
.vagrant/

68
Vagrantfile vendored Normal file
View file

@ -0,0 +1,68 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "debian/jessie64"
config.vm.hostname = "gvaldap.local"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# 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: 8001
# 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.10"
config.vm.network "private_network", ip: "172.16.3.3"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# 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 "../data", "/vagrant_data"
config.vm.synced_folder "salt/roots/", "/srv/salt/"
config.vm.synced_folder "salt/pillar/", "/srv/pillar/"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
vb.memory = "512"
end
config.vm.provision :salt do |salt|
salt.bootstrap_script = "salt/bootstrap.sh"
salt.minion_id = "gvadev"
salt.masterless = true
salt.run_highstate = true
salt.verbose = true
salt.colorize = true
salt.log_level = "warning"
end
end

31
salt/bootstrap.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/sh -
# We just download the bootstrap script by default and execute that.
if [ -x /usr/bin/fetch ]; then
/usr/bin/fetch -o - https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh | sh -s -- "$@"
elif [ -x /usr/bin/curl ]; then
/usr/bin/curl -L https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh | sh -s -- "$@"
else
python \
-c 'import urllib; print urllib.urlopen("https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh").read()' \
| sh -s -- "$@"
fi
cat >/etc/salt/minion <<EOF
file_client: local
file_roots:
base:
- /srv/salt/
pillar_roots:
base:
- /srv/pillar
log_file: file:///dev/log
EOF
cat >/etc/salt/grains <<EOF
roles:
- gnuviechadmin.gvaldap
EOF

0
salt/grains Normal file
View file

11
salt/minion Normal file
View file

@ -0,0 +1,11 @@
file_client: local
file_roots:
base:
- /srv/salt/
pillar_roots:
base:
- /srv/pillar
log_file: file:///dev/log

View file

@ -0,0 +1,8 @@
include:
- gnuviechadmin.database.common
gnuviechadmin:
database:
owner:
user: gnuviechadmin
password: k4TG0oWeJ08urz697GVfavjK

View file

@ -0,0 +1,5 @@
gnuviechadmin:
database:
name: gnuviechadmin
host: localhost
port: 5432

View file

@ -0,0 +1,8 @@
include:
- gnuviechadmin.queues.common
- gnuviechadmin.queues.gvaldap
gnuviechadmin:
component:
name: gvaldap
amqp_user: ldap

View file

@ -0,0 +1,16 @@
gnuviechadmin:
deploymenttype: local
mailfrom: admin@gnuviech-server.de
adminemail: admin@gnuviech-server.de
sitename: Gnuviech Customer Self Service
domainname: localhost
devinstance: True
minosuid: 10000
minosgid: 10000
osuserprefix: usr
osuserhomedirbase: /home
osuserdefaultshell: /usr/bin/rssh
uploadserver: gvafile.local
webmail_url: https://webmail.example.com/
phpmyadmin_url: https://phpmyadmin.example.com/
phppgadmin_url: https://phppgadmin.example.com/

View file

@ -0,0 +1,77 @@
include:
- gnuviechadmin.queues.common
- gnuviechadmin.queues.gvaldap
- gnuviechadmin.queues.gvafile
- gnuviechadmin.queues.cli
- gnuviechadmin.queues.gva
- gnuviechadmin.queues.gvamysql
- gnuviechadmin.queues.gvapgsql
- gnuviechadmin.queues.gvaweb
gnuviechadmin:
queues:
users:
ldap:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
file:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
gva:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
mysql:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
pgsql:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
web:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
cli:
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
quotajob:
perms:
'/gnuviechadmin':
- '^quotatool$'
- '^quotatool$'
- '^quotatool|amq.default$'
tags:
admin:
password: MmE3Iwylj8Sgy46Z
perms:
'/gnuviechadmin':
- '.*'
- '.*'
- '.*'
tags:
- administrator

View file

@ -0,0 +1,7 @@
gnuviechadmin:
queues:
users:
cli:
password: bUQ4QEB8yQEfsB0i
quotajob:
password: TaNoj2H3ZNDIz1rt

View file

@ -0,0 +1,3 @@
gnuviechadmin:
queues:
vhost: /gnuviechadmin

View file

@ -0,0 +1,5 @@
gnuviechadmin:
queues:
users:
gva:
password: Y5KmkIou7o8J9jV5

View file

@ -0,0 +1,5 @@
gnuviechadmin:
queues:
users:
file:
password: StR6EgMjLyNGP1F8

View file

@ -0,0 +1,5 @@
gnuviechadmin:
queues:
users:
ldap:
password: tl0ALc4aQBAl0W2e

View file

@ -0,0 +1,5 @@
gnuviechadmin:
queues:
users:
mysql:
password: Bhruvz8Oe9rXxRc7

View file

@ -0,0 +1,5 @@
gnuviechadmin:
queues:
users:
pgsql:
password: rWOawAtb7MEmGZo3

View file

@ -0,0 +1,5 @@
gnuviechadmin:
queues:
users:
web:
password: 1fBXqCu175rU7SWA

View file

@ -0,0 +1,9 @@
include:
- gnuviechadmin.queues.common
- gnuviechadmin.queues.gva
gnuviechadmin:
component:
name: gva
amqp_user: gva
python_module: gnuviechadmin

8
salt/pillar/top.sls Normal file
View file

@ -0,0 +1,8 @@
base:
'*':
- gnuviechadmin
{% for role in ('database', 'queues', 'webinterface', 'gvaldap', 'gvafile', 'gvamysql', 'gvapgsql', 'gvaweb') %}
'roles:gnuviechadmin.{{ role }}':
- match: grain
- gnuviechadmin.{{ role }}
{% endfor %}

View file

@ -0,0 +1,117 @@
# -*- coding: utf-8 -*-
#
# some internal functions are copied from salt.states.file
from Crypto.PublicKey import RSA
import os
def _check_user(user, group):
'''
Checks if the named user and group are present on the minion
'''
err = ''
if user:
uid = __salt__['file.user_to_uid'](user)
if uid == '':
err += 'User {0} is not available '.format(user)
if group:
gid = __salt__['file.group_to_gid'](group)
if gid == '':
err += 'Group {0} is not available'.format(group)
return err
def _error(ret, err_msg):
ret['result'] = False
ret['comment'] = err_msg
return ret
def _calculate_umask(mode):
mode = str(mode).lstrip('0')
if not mode:
mode = '0'
modeint = int(mode, 8)
return modeint ^ 0777
def valid_key(name, bits=2048, user=None, group=None, mode='0700'):
"""
Make sure that the given key file exists and contains a valid RSA key.
name
The name of the key file to check
bits
Minimum bits for the RSA key
user
The user to own the file, this defaults to the user salt is running as
on the minion
group
The group ownership set for the file, this defaults to the group salt
is running on the minion
mode
The permissions set on the file, this defaults to 0600
"""
mode = __salt__['config.manage_mode'](mode)
ret = {
'name': name,
'changes': {},
'result': None,
'comment': ''}
if not os.path.isfile(name) and __opts__['test']:
ret['comment'] = 'would create RSA key in file {0}'.format(name)
return ret
u_check = _check_user(user, group)
if u_check:
return _error(ret, u_check)
if not os.path.isabs(name):
return _error(
ret, 'Specified file {0} is not an absolute path'.format(name))
if os.path.isdir(name):
return _error(
ret, 'Specified target {0} is a directory'.format(name))
if os.path.exists(name):
ret, perms = __salt__['file.check_perms'](
name, ret, user, group, mode)
if __opts__['test']:
ret['comment'] = 'File {0} not updated'.format(name)
return ret
if not os.path.isfile(name):
rsa = RSA.generate(bits)
oldumask = os.umask(_calculate_umask(mode))
with open(name, 'w') as rsafile:
rsafile.write(rsa.exportKey())
os.umask(oldumask)
ret['comment'] = 'created new RSA key and saved PEM file {0}'.format(
name)
ret['changes']['created'] = name
ret['result'] = True
return ret
try:
with open(name, 'r') as rsafile:
rsa = RSA.importKey(rsafile.read())
except Exception as e:
ret['comment'] = 'error loading RSA key from file {0}: {1}'.format(
name, e)
ret['result'] = False
return ret
keysize = rsa.size() + 1
if keysize < bits:
ret['comment'] = (
'RSA key in {0} is only {1} bits, which is less than the '
'required {2} bits'.format(name, keysize, bits))
ret['result'] = False
else:
ret['comment'] = 'RSA key in file {0} is ok ({1} bits)'.format(
name, keysize)
ret['result'] = True
return ret

View file

@ -0,0 +1,61 @@
# -*- coding: utf8 -*-
'''
Manage X.509 certificate life cycle
===================================
This state is useful for managing X.509 certificates' life cycles.
Copyright (c) 2014 Jan Dittberner <jan@dittberner.info>
'''
from M2Crypto import X509
from datetime import datetime
import os
def _error(ret, err_msg):
ret['result'] = False
ret['comment'] = err_msg
return ret
def valid_certificate(
name, mindays=14, keyfile=None,
checkchain=False, trustedcerts=None):
'''
Checks whether the given certificate file is valid.
name
The name of the certificate file to check
mindays
Mark the certificate as invalid if it is valid for less then this many
days
'''
ret = {
'name': name,
'changes': {},
'result': None,
'comment': ''}
if not os.path.isfile(name):
return _error(
ret, 'certificate file {0} does not exist'.format(name))
try:
cert = X509.load_cert(name)
except Exception as e:
return _error(
ret,
'error loading certificate {0}: {1}'.format(name, e))
notafter = cert.get_not_after().get_datetime()
delta = notafter - datetime.now(notafter.tzinfo)
if delta.days < mindays:
return _error(
ret,
'certificate {0} is only valid for {1} more day(s)'.format(
name, delta.days))
# TODO: check keyfile match
# TODO: check trust chain
ret['comment'] = (
'certificate {0} is ok and still valid for {1} days'.format(
name, delta.days))
ret['result'] = True
return ret

View file

@ -0,0 +1,25 @@
#!/bin/bash
function devenv
{
. $HOME/gvasettings.sh
. {{ venv }}/bin/activate
cd {{ appdir }}
}
function testenv
{
devenv
export DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE%%.local}.test
}
function settitle
{
if [ -n "$STY" ] ; then # We are in a screen session
echo "Setting screen titles to $@"
printf "\033k%s\033\\" "$@"
screen -X eval "at \\# title $@" "shelltitle $@"
else
printf "\033]0;%s\007" "$@"
fi
}

117
salt/roots/base/bashrc Normal file
View file

@ -0,0 +1,117 @@
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
#alias grep='grep --color=auto'
#alias fgrep='fgrep --color=auto'
#alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
if [ -f ~/.bash_functions ]; then
. ~/.bash_functions
fi

30
salt/roots/base/init.sls Normal file
View file

@ -0,0 +1,30 @@
base-packages:
pkg.installed:
- pkgs:
- screen
- htop
- git
/home/vagrant/.screenrc:
file.managed:
- user: vagrant
- group: vagrant
- mode: 0644
- source: salt://base/screenrc
update-system:
pkg.uptodate:
- refresh: True
/home/vagrant/bin:
file.directory:
- user: vagrant
- group: vagrant
- mode: 0750
/home/vagrant/.bashrc:
file.managed:
- user: vagrant
- group: vagrant
- mode: 0644
- source: salt://base/bashrc

14
salt/roots/base/screenrc Normal file
View file

@ -0,0 +1,14 @@
# vim: syntax=screen
hardstatus on
hardstatus alwayslastline
hardstatus string "%{= r}[ %{G}%H%{= r} ] %= %{=b b}%-w%{=rb db}%>%n %t%{-}%+w %=%{= r} [ %{G}%c %{M}%D %m-%d %{r}]"
startup_message off
defscrollback 10240
bind f eval "caption splitonly" "hardstatus ignore"
bind F eval "caption always" "hardstatus alwayslastline"
defbce "on"

View file

@ -0,0 +1,98 @@
{% from 'gnuviechadmin/vars.sls' import home, gva_component, gva_amqp_user, checkout, appdir, venv %}
gva.local:
host.present:
- ip: 172.16.3.2
- names:
- mq
- gva.local
gvaldap.local:
host.present:
- ip: 172.16.3.3
gvafile.local:
host.present:
- ip: 172.16.3.4
gvaweb.local:
host.present:
- ip: 172.16.3.5
gvamysql.local:
host.present:
- ip: 172.16.3.6
gvapgsql.local:
host.present:
- ip: 172.16.3.7
gnuviechadmin-packages:
pkg.installed:
- pkgs:
- libyaml-dev
- python-virtualenv
- python-dev
- python-pip
- gettext
{{ home }}/gvasettings.sh:
file.managed:
- user: vagrant
- group: vagrant
- mode: 0640
- source: salt://gnuviechadmin/{{ gva_component }}/settings.sh
- template: jinja
- context:
broker_url: {{ 'amqp://%s:%s@mq/%s' % (gva_amqp_user, salt['pillar.get']('gnuviechadmin:queues:users:%s:password' % gva_amqp_user), salt['pillar.get']('gnuviechadmin:queues:vhost')) }}
gnuviechadmin-venv:
cmd.run:
- name: virtualenv {{ venv }}
- user: vagrant
- group: vagrant
- unless: test -f {{ venv }}/bin/pip
gnuviechadmin-requires:
cmd.run:
- name: {{ venv }}/bin/pip install -U -r requirements/local.txt && touch {{ venv }}/lastinstall
- user: vagrant
- group: vagrant
- cwd: {{ checkout }}
- require:
- cmd: gnuviechadmin-venv
- pkg: gnuviechadmin-packages
- unless: test -e {{ venv }}/lastinstall && test {{ checkout }}/requirements/local.txt -ot {{ venv }}/lastinstall && test {{ checkout }}/requirements/base.txt -ot {{ venv }}/lastinstall
gnuviechadmin-dbschema:
cmd.wait:
- name: . {{ home }}/gvasettings.sh ; unset LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME ; {{ venv }}/bin/python manage.py migrate --noinput
- user: vagrant
- group: vagrant
- cwd: {{ appdir }}
- watch:
- cmd: gnuviechadmin-requires
- file: {{ home }}/gvasettings.sh
gnuviechadmin-locale-data-compile:
cmd.wait:
- name: . {{ home }}/gvasettings.sh ; {{ venv }}/bin/python {{ appdir }}/manage.py compilemessages
- user: vagrant
- group: vagrant
- cwd: {{ appdir }}
- require:
- pkg: gnuviechadmin-packages
- file: {{ home }}/gvasettings.sh
- cmd: gnuviechadmin-venv
/home/vagrant/.bash_functions:
file.managed:
- user: vagrant
- group: vagrant
- mode: 0644
- source: salt://base/bash_functions
- template: jinja
- context:
home: {{ home }}
venv: {{ venv }}
appdir: {{ appdir }}

View file

@ -0,0 +1,25 @@
#!/bin/bash
function devenv
{
. $HOME/gvasettings.sh
. $HOME/gva-venv/bin/activate
cd /vagrant/gnuviechadmin
}
function testenv
{
devenv
export DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE%%.local}.test
}
function settitle
{
if [ -n "$STY" ] ; then # We are in a screen session
echo "Setting screen titles to $@"
printf "\033k%s\033\\" "$@"
screen -X eval "at \\# title $@" "shelltitle $@"
else
printf "\033]0;%s\007" "$@"
fi
}

View file

@ -0,0 +1,13 @@
{% from 'gnuviechadmin/vars.sls' import home, gva_component, venv, appdir %}
{{ home }}/bin/run_celery.sh:
file.managed:
- user: vagrant
- group: vagrant
- mode: 0750
- source: salt://gnuviechadmin/{{ gva_component }}/run_celery.sh
- template: jinja
- context:
home: {{ home }}
virtualenv: {{ venv }}
appdir: {{ appdir }}

View file

@ -0,0 +1,33 @@
include:
- postgresql-server
gnuviechadmin-database:
postgres_user.present:
- name: {{ salt['pillar.get']('gnuviechadmin:database:owner:user') }}
- user: postgres
- password: {{ salt['pillar.get']('gnuviechadmin:database:owner:password') }}
- login: True
- createdb: {% if salt['pillar.get']('gnuviechadmin:deploymenttype', 'production') == 'local' %}True
{%- else %}False
{%- endif %}
- require:
- service: postgresql
postgres_database.present:
- name: {{ salt['pillar.get']('gnuviechadmin:database:name') }}
- user: postgres
- owner: {{ salt['pillar.get']('gnuviechadmin:database:owner:user') }}
- encoding: UTF8
- template: template0
- require:
- service: postgresql
- postgres_user: {{ salt['pillar.get']('gnuviechadmin:database:owner:user') }}
{% for gnuviechadmin_db_role in salt['pillar.get']('gnuviechadmin:database:users') %}
gnuviechadmin-dbuser-{{ gnuviechadmin_db_role }}:
postgres_user.present:
- name: {{ salt['pillar.get']('gnuviechadmin:database:users:%s:user' % gnuviechadmin_db_role) }}
- password: {{ salt['pillar.get']('gnuviechadmin:database:users:%s:password' % gnuviechadmin_db_role) }}
- login: True
- require:
- service: postgresql
{% endfor %}

View file

@ -0,0 +1,27 @@
server {
server_name www.{{ domainname }};
listen 443 ssl;
ssl_certificate {{ ssl_certdir }}/{{ domainname }}.crt.pem;
ssl_certificate_key {{ ssl_keydir }}/{{ domainname }}.key.pem;
if ( $host != '{{ domainname }}') {
return 301 https://{{ domainname }}$request_uri;
}
client_max_body_size 1M;
gzip on;
gzip_types text/javascript application/x-javascript text/css;
location /media {
alias /vagrant/gnuviechadmin/media;
}
location /static {
alias /vagrant/gnuviechadmin/assets;
}
location / {
proxy_pass http://localhost:8000;
}
}

View file

@ -0,0 +1,24 @@
#!/bin/sh
export DJANGO_SETTINGS_MODULE="gnuviechadmin.settings.{{ salt['pillar.get']('gnuviechadmin:deploymenttype', 'production') }}"
export GVA_ADMIN_NAME="Jan Dittberner"
export GVA_ADMIN_EMAIL="{{ salt['pillar.get']('gnuviechadmin:adminemail') }}"
export GVA_PGSQL_DATABASE="{{ salt['pillar.get']('gnuviechadmin:database:name') }}"
export GVA_PGSQL_USER="{{ salt['pillar.get']('gnuviechadmin:database:owner:user') }}"
export GVA_PGSQL_PASSWORD="{{ salt['pillar.get']('gnuviechadmin:database:owner:password') }}"
export GVA_PGSQL_HOSTNAME="{{ salt['pillar.get']('gnuviechadmin:database:host') }}"
export GVA_PGSQL_PORT={{ salt['pillar.get']('gnuviechadmin:database:port') }}
export GVA_DOMAIN_NAME="{{ salt['pillar.get']('gnuviechadmin:domainname') }}"
export GVA_SITE_NAME="{{ salt['pillar.get']('gnuviechadmin:sitename') }}"
export GVA_SITE_SECRET="{{ salt['grains.get_or_set_hash']('gnuviechadmin:SECRET_KEY', 50) }}"
export GVA_SITE_ADMINMAIL="{{ salt['pillar.get']('gnuviechadmin:adminemail') }}"
export GVA_MIN_OS_UID={{ salt['pillar.get']('gnuviechadmin:minosuid') }}
export GVA_MIN_OS_GID={{ salt['pillar.get']('gnuviechadmin:minosgid') }}
export GVA_OSUSER_PREFIX="{{ salt['pillar.get']('gnuviechadmin:osuserprefix') }}"
export GVA_OSUSER_HOME_BASEPATH="{{ salt['pillar.get']('gnuviechadmin:osuserhomedirbase') }}"
export GVA_OSUSER_DEFAULT_SHELL="{{ salt['pillar.get']('gnuviechadmin:osuserdefaultshell') }}"
export GVA_BROKER_URL="{{ broker_url }}"
export GVA_OSUSER_UPLOADSERVER="{{ salt['pillar.get']('gnuviechadmin:uploadserver') }}"
export GVA_WEBMAIL_URL="{{ salt['pillar.get']('gnuviechadmin:webmail_url') }}"
export GVA_PHPMYADMIN_URL="{{ salt['pillar.get']('gnuviechadmin:phpmyadmin_url') }}"
export GVA_PHPPGADMIN_URL="{{ salt['pillar.get']('gnuviechadmin:phppgadmin_url') }}"

View file

@ -0,0 +1,11 @@
include:
- gnuviechadmin.base
- gnuviechadmin.celery
gvaldap-packages:
pkg.installed:
- pkgs:
- libldap2-dev
- libsasl2-dev
- require_in:
- pkg: gnuviechadmin-packages

View file

@ -0,0 +1,7 @@
#!/bin/sh
set -ex
. {{ home }}/gvasettings.sh
cd {{ appdir }}
{{ virtualenv }}/bin/celery worker -A gvaldap -Q ldap --loglevel=INFO

View file

@ -0,0 +1,14 @@
#!/bin/sh
export DJANGO_SETTINGS_MODULE="gvaldap.settings.{{ salt['pillar.get']('gnuviechadmin:deploymenttype', 'production') }}"
export GVALDAP_ADMIN_NAME="Jan Dittberner"
export GVALDAP_ADMIN_EMAIL="{{ salt['pillar.get']('gnuviechadmin-gvaldap:admin_email') }}"
export GVALDAP_LDAP_URL="{{ salt['pillar.get']('gnuviechadmin-gvaldap:ldap_url') }}"
export GVALDAP_LDAP_USER="{{ salt['pillar.get']('gnuviechadmin-gvaldap:ldap_user') }}"
export GVALDAP_LDAP_PASSWORD="{{ salt['pillar.get']('gnuviechadmin-gvaldap:ldap_password' ) }}"
export GVALDAP_BASEDN_GROUP="{{ salt['pillar.get']('gnuviechadmin-gvaldap:basedn_group') }}"
export GVALDAP_BASEDN_USER="{{ salt['pillar.get']('gnuviechadmin-gvaldap:basedn_user') }}"
export GVALDAP_SECRETKEY="{{ salt['grains.get_or_set_hash']('gnuviechadmin-gvaldap:SECRET_KEY', 50) }}"
export GVALDAP_BROKER_URL="{{ broker_url }}"
export GVALDAP_ALLOWED_HOSTS="{{ salt['pillar.get']('gnuviechadmin-gvaldap:allowed_hosts') }}"
export GVALDAP_SERVER_EMAIL="{{ salt['pillar.get']('gnuviechadmin-gvaldap:server_email') }}"

View file

@ -0,0 +1,30 @@
include:
- rabbitmq-server
gnuviechadmin-queue-vhost:
rabbitmq_vhost.present:
- name: {{ salt['pillar.get']('gnuviechadmin:queues:vhost') }}
{% for user in salt['pillar.get']('gnuviechadmin:queues:users') %}
gnuviechadmin-queue-user-{{ user }}:
rabbitmq_user.present:
- name: {{ user }}
- password: {{ salt['pillar.get']('gnuviechadmin:queues:users:%s:password' % user) }}
{% if salt['pillar.get']('gnuviechadmin:queues:users:%s:perms' % user) %}
- perms:
{% for vhost, perms in salt['pillar.get']('gnuviechadmin:queues:users:%s:perms' % user).iteritems() %}
- {{ vhost }}:
- {{ perms[0] }}
- {{ perms[1] }}
- {{ perms[2] }}
{% endfor %}
{% endif %}
{% if salt['pillar.get']('gnuviechadmin:queues:users:%s:tags' % user) %}
- tags:
{% for tag in salt['pillar.get']('gnuviechadmin:queues:users:%s:tags' % user) %}
- {{ tag }}
{% endfor %}
{% endif %}
- require:
- rabbitmq_vhost: {{ salt['pillar.get']('gnuviechadmin:queues:vhost') }}
{% endfor %}

View file

@ -0,0 +1,7 @@
{% set home = '/home/vagrant' %}
{% set venv = home + '/gva-venv' %}
{% set checkout = '/vagrant' %}
{% set gva_component = salt['pillar.get']('gnuviechadmin:component:name') %}
{% set gva_amqp_user = salt['pillar.get']('gnuviechadmin:component:amqp_user') %}
{% set python_module = salt['pillar.get']('gnuviechadmin:component:python_module', gva_component) %}
{% set appdir = checkout + '/' + python_module %}

View file

@ -0,0 +1,39 @@
include:
- gnuviechadmin.base
- webserver
libpq-dev:
pkg.installed:
- require_in:
- pkg: gnuviechadmin-packages
python-m2crypto:
pkg.installed:
- reload_modules: true
{% import "webserver/sslcert.macros.sls" as sslcert %}
{% set domainname = salt['pillar.get']('gnuviechadmin:domainname') %}
{{ sslcert.key_cert(domainname) }}
/etc/nginx/sites-available/{{ domainname }}:
file.managed:
- user: root
- group: root
- mode: 0640
- source: salt://gnuviechadmin/gva/gnuviechadmin.nginx
- template: jinja
- context:
domainname: {{ domainname }}
ssl_keydir: {{ salt['pillar.get']('nginx:sslkeydir', '/etc/nginx/ssl/private') }}
ssl_certdir: {{ salt['pillar.get']('nginx:sslcertdir', '/etc/nginx/ssl/certs') }}
- require:
- pkg: nginx
/etc/nginx/sites-enabled/{{ domainname }}:
file.symlink:
- target: /etc/nginx/sites-available/{{ domainname }}
- require:
- file: /etc/nginx/sites-available/{{ domainname }}
- watch_in:
- service: nginx

38
salt/roots/nginx/init.sls Normal file
View file

@ -0,0 +1,38 @@
nginx:
pkg:
- installed
service.running:
- enable: True
- require:
- pkg: nginx
nginx-common:
pkg.installed
/etc/nginx/nginx.conf:
file.managed:
- source: salt://nginx/nginx.conf
- user: root
- group: root
- mode: 0644
- require:
- pkg: nginx-common
- watch_in:
- service: nginx
{% set nginx_ssl_keydir = salt['pillar.get']('nginx:sslkeydir', '/etc/nginx/ssl/private') %}
{% set nginx_ssl_certdir = salt['pillar.get']('nginx:sslcertdir', '/etc/nginx/ssl/certs') %}
{{ nginx_ssl_certdir }}:
file.directory:
- user: root
- group: root
- mode: 0755
- makedirs: True
{{ nginx_ssl_keydir }}:
file.directory:
- user: root
- group: root
- mode: 0750
- makedirs: True

View file

@ -0,0 +1,49 @@
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

View file

@ -0,0 +1,9 @@
locales-all:
pkg.installed
postgresql:
pkg:
- installed
service.running:
- require:
- pkg: postgresql

View file

@ -0,0 +1,17 @@
rabbitmq-server:
pkg:
- installed
service:
- running
- requires:
- pkg: rabbitmq-server
guest:
rabbitmq_user:
- absent
rabbitmq_management:
rabbitmq_plugin:
- enabled
- watch_in:
- service: rabbitmq-server

11
salt/roots/top.sls Normal file
View file

@ -0,0 +1,11 @@
base:
'*':
- vim
- base
{% if 'roles' in grains %}
{% for role in grains['roles'] %}
'roles:{{ role }}':
- match: grain
- {{ role }}
{% endfor %}
{% endif %}

15
salt/roots/vim/init.sls Normal file
View file

@ -0,0 +1,15 @@
vim-nox:
pkg.installed
editor:
alternatives.set:
- path: /usr/bin/vim.nox
- require:
- pkg: vim-nox
/home/vagrant/.vimrc:
file.managed:
- user: vagrant
- group: vagrant
- mode: 0644
- source: salt://vim/vimrc

34
salt/roots/vim/vimrc Normal file
View file

@ -0,0 +1,34 @@
syntax on
set showcmd
set modeline
set modelines=3
set expandtab
set shiftwidth=4
set autoindent
set smarttab
set ruler
set list listchars=tab:▷⋅,trail:⋅,nbsp:⋅
set cpoptions+=$
set hlsearch
set virtualedit=all
set guioptions-=T
set guioptions-=m
set wildmenu
set complete=.,w,b,u,t
set number
filetype plugin indent on
autocmd BufNewFile,BufRead *.sls set filetype=yaml
autocmd FileType make set noexpandtab
autocmd FileType python set tabstop=4 shiftwidth=4 autoindent smartindent textwidth=79
autocmd FileType html set tabstop=2 shiftwidth=2 textwidth=200 smartindent autoindent
autocmd FileType htmldjango set tabstop=2 shiftwidth=2 textwidth=200
autocmd FileType moin set tabstop=2 shiftwidth=2
autocmd FileType rst set textwidth=79
autocmd FileType yaml set tabstop=2 shiftwidth=2
set laststatus=2
set statusline=%f%m%r%h%w\ [TYPE=%Y\ %{&ff}]\ \ [%c\ @\ %l/%L]\ (%p%%)\ [%b\ 0x%B]

View file

@ -0,0 +1,50 @@
include:
- nginx
/etc/nginx/conf.d/logformat.conf:
file.managed:
- user: root
- group: root
- mode: 0644
- source: salt://webserver/nginx-logformat.conf
- require:
- pkg: nginx
- watch_in:
- service: nginx
{% set ssldir = salt['pillar.get']('nginx:sslcertdir', '/etc/nginx/ssl/certs') %}
generate-dhparam-nginx:
cmd.run:
- name: openssl dhparam -out {{ ssldir }}/dhparams.pem 2048
- umask: 022
- user: root
- group: root
- creates: {{ ssldir }}/dhparams.pem
- require_in:
- file: /etc/nginx/conf.d/ssl.conf
- watch_in:
- service: nginx
/etc/nginx/conf.d/ssl.conf:
file.managed:
- user: root
- group: root
- mode: 0644
- source: salt://webserver/nginx-ssl.conf
- template: jinja
- require:
- pkg: nginx
- watch_in:
- service: nginx
/etc/nginx/snippets/security.conf:
file.managed:
- user: root
- group: root
- mode: 0644
- source: salt://webserver/nginx-security.conf
- require:
- pkg: nginx
- watch_in:
- service: nginx

View file

@ -0,0 +1,4 @@
log_format main '$remote_addr - $remote_user [$time_local] '
'$server_name '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';

View file

@ -0,0 +1,19 @@
# Security - Basic configuration
location = /favicon.ico {
log_not_found off;
access_log off;
expires max;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}

View file

@ -0,0 +1,15 @@
# Default TLS settings
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers kEECDH+AESGCM:kEECDH+AES:kEECDH:EDH+AESGCM:kEDH+AES:kEDH:AESGCM:ALL:!LOW:!EXP:!MD5:!aNULL:!eNULL:!RC4:!DSS;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_dhparam {{ salt['pillar.get']('nginx:sslcertdir', '/etc/nginx/ssl/certs') }}/dhparams.pem;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# use Google's DNS
resolver 8.8.8.8;
resolver_timeout 5s;

View file

@ -0,0 +1,30 @@
{%- macro key_cert(domain_name) %}
{% set nginx_ssl_keydir = salt['pillar.get']('nginx:sslkeydir', '/etc/nginx/ssl/private') %}
{% set nginx_ssl_certdir = salt['pillar.get']('nginx:sslcertdir', '/etc/nginx/ssl/certs') %}
{% set keyfile = nginx_ssl_keydir + '/' + domain_name + '.key.pem' %}
{% set certfile = nginx_ssl_certdir + '/' + domain_name + '.crt.pem' %}
{{ keyfile }}:
rsa_key.valid_key:
- bits: {{ salt['pillar.get']('nginx:keylength:' + domain_name, 2048) }}
- require:
- file: {{ nginx_ssl_keydir }}
- require_in:
- file: /etc/nginx/sites-available/{{ domain_name }}
- service: nginx
{{ certfile }}:
cmd.run:
- name: openssl req -new -x509 -key {{ keyfile }} -subj '/CN={{ domain_name }}' -days 730 -out {{ certfile }}
- require:
- rsa_key: {{ keyfile }}
- creates: {{ certfile }}
x509_certificate.valid_certificate:
- require:
- file: {{ nginx_ssl_certdir }}
- cmd: {{ certfile }}
- pkg: python-m2crypto
- require_in:
- file: /etc/nginx/sites-available/{{ domain_name }}
- service: nginx
{% endmacro %}