cleanning debian branch
This commit is contained in:
parent
e31d6413d5
commit
19b4516525
48
README
48
README
|
@ -1,48 +0,0 @@
|
|||
wcsinst
|
||||
=======
|
||||
|
||||
wcsinst is a web application to deploy w.c.s. instances; it is released under
|
||||
the GNU AGPL Licence.
|
||||
|
||||
|
||||
Architecture
|
||||
------------
|
||||
|
||||
This project is composed of two Django applications; wcsinst provides a model
|
||||
and is expected to be installed as part of an administrative portal; wcsinstd
|
||||
provides the web API to deploy w.c.s. instances and should be installed on its
|
||||
own, on the host instances should be deployed.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
If the WCSINSTD_URL environment variable is set, ./manage.py will run itself as
|
||||
a standalone wcsinst (admin) site. Go to /admin/.
|
||||
|
||||
Example: WCSINSTD_URL=http://127.0.0.1:8001/ ./manage.py runserver
|
||||
|
||||
The wcsinstd application expects a WCSINST_WCS_APP_DIR setting, that should
|
||||
point to the w.c.s. application directory (typically /var/lib/wcs/).
|
||||
|
||||
Additionally it expects site skeletons to be made available from the
|
||||
media/skeletons directory; the default skeleton should go in a subdirectory
|
||||
named "default".
|
||||
|
||||
A skeleton directory has the following files:
|
||||
|
||||
- export.wcs: as produced from wcs, admin/export
|
||||
- idff-metadata-template: template file for ID-FF 1.2 metadata (optional)
|
||||
- saml2-metadata-template: template file for SAMLv2 metadata (optional)
|
||||
- private-key.pem & public-key.pem: pair of keys for ID-FF/SAML (optional)
|
||||
- idp-metadata.xml: metadata of the identity provider (optional)
|
||||
- site-options.cfg: template file for the w.c.s. site-options.cfg file
|
||||
- apache-vhost.conf: tempalte file for the Apache virtual host configuration
|
||||
|
||||
The template files contains template strings (cf the Python documentation);
|
||||
there is a single variable made available, named domain (hence ${domain} to
|
||||
use it).
|
||||
|
||||
The wcsinstd application should be able to run "sudo -n /etc/init.d/apache2
|
||||
reload", to reload virtual hosts configuration. Virtual host configuration
|
||||
files are created in $media/vhosts.d
|
|
@ -1,178 +0,0 @@
|
|||
# Django settings for wcsinst project.
|
||||
|
||||
import os
|
||||
import json
|
||||
import logging.handlers
|
||||
import wcsinst
|
||||
|
||||
DEBUG = 'DEBUG' in os.environ
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
VAR_DIR = '/var/lib/wcsinstd'
|
||||
PROJECT_PATH = os.path.dirname(wcsinst.__file__)
|
||||
|
||||
if 'ADMINS' in os.environ:
|
||||
ADMINS = [ x.split(';') for x in os.environ['ADMINS'].split(',') ]
|
||||
else:
|
||||
ADMINS = ( ('root', 'root@localhost') )
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(VAR_DIR, 'wcsinst.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
# Hosts/domain names that are valid for this site; required if DEBUG is False
|
||||
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
|
||||
if 'ALLOWED_HOSTS' in os.environ:
|
||||
ALLOWED_HOSTS = os.environ['ALLOWED_HOSTS'].split(',')
|
||||
else:
|
||||
ALLOWED_HOSTS = [ '*' ]
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# In a Windows environment this must be set to your system time zone.
|
||||
TIME_ZONE = 'Europe/Brussels'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'fr-fr'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale.
|
||||
USE_L10N = True
|
||||
|
||||
# If you set this to False, Django will not use timezone-aware datetimes.
|
||||
USE_TZ = True
|
||||
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
# Example: "/var/www/example.com/media/"
|
||||
MEDIA_ROOT = os.path.join(VAR_DIR, 'media')
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://example.com/media/", "http://media.example.com/"
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
# Absolute path to the directory static files should be collected to.
|
||||
# Don't put anything in this directory yourself; store your static files
|
||||
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
|
||||
# Example: "/var/www/example.com/static/"
|
||||
STATIC_ROOT = os.path.join(VAR_DIR, 'static')
|
||||
|
||||
# URL prefix for static files.
|
||||
# Example: "http://example.com/static/", "http://static.example.com/"
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Additional locations of static files
|
||||
STATICFILES_DIRS = (
|
||||
os.path.join(VAR_DIR, 'extra-static'),
|
||||
)
|
||||
|
||||
# List of finder classes that know how to find static files in
|
||||
# various locations.
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||
)
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY') or file('/etc/wcsinstd/secret').read()
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
# Uncomment the next line for simple clickjacking protection:
|
||||
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'wcsinst.urls'
|
||||
|
||||
# Python dotted path to the WSGI application used by Django's runserver.
|
||||
WSGI_APPLICATION = 'wcsinst.wsgi.application'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
os.path.join(PROJECT_PATH, 'wcsinst', 'templates'),
|
||||
os.path.join(VAR_DIR, 'templates'),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'south',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.admin',
|
||||
)
|
||||
|
||||
# A sample logging configuration. The only tangible logging
|
||||
# performed by this configuration is to send an email to
|
||||
# the site admins on every HTTP 500 error when DEBUG=False.
|
||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
||||
# more details on how to customize your logging configuration.
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': True,
|
||||
'formatters': {
|
||||
'syslog': {
|
||||
'format': 'wcsinstd(pid=%(process)d) %(levelname)s %(name)s: %(message)s',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'filters': [],
|
||||
'class': 'django.utils.log.AdminEmailHandler'
|
||||
},
|
||||
'syslog': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'entrouvert.logging.handlers.SysLogHandler',
|
||||
'formatter': 'syslog',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL0,
|
||||
'address': '/dev/log',
|
||||
'max_length': 999,
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'': {
|
||||
'handlers': ['mail_admins','syslog'],
|
||||
'level': 'DEBUG' if DEBUG else 'INFO',
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
INSTALLED_APPS += ('wcsinst.wcsinstd',)
|
||||
|
||||
if 'SENTRY_DSN' in os.environ:
|
||||
INSTALLED_APPS += ('raven.contrib.django.raven_compat',)
|
||||
RAVEN_CONFIG = {
|
||||
'dsn': os.environ.get('SENTRY_DSN'),
|
||||
}
|
||||
|
||||
for var in ('WCSINST_WCSCTL_SCRIPT', 'WCSINST_URL_TEMPLATE', 'WCSINST_WCS_APP_DIR'):
|
||||
if var in os.environ:
|
||||
globals()[var] = os.environ[var]
|
|
@ -1,32 +0,0 @@
|
|||
"""
|
||||
WSGI config for wcsinst project.
|
||||
|
||||
This module contains the WSGI application used by Django's development server
|
||||
and any production WSGI deployments. It should expose a module-level variable
|
||||
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
|
||||
this application via the ``WSGI_APPLICATION`` setting.
|
||||
|
||||
Usually you will have the standard Django WSGI application here, but it also
|
||||
might make sense to replace the whole Django WSGI application with a custom one
|
||||
that later delegates to the Django one. For example, you could introduce WSGI
|
||||
middleware here, or combine a Django application with an application of another
|
||||
framework.
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
||||
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
||||
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
||||
# os.environ["DJANGO_SETTINGS_MODULE"] = "wcsinst.settings"
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "debian_settings")
|
||||
|
||||
# This application object is used by any WSGI server configured to use this
|
||||
# file. This includes Django's development server, if the WSGI_APPLICATION
|
||||
# setting points here.
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
|
||||
# Apply WSGI middleware here.
|
||||
# from helloworld.wsgi import HelloWorldApplication
|
||||
# application = HelloWorldApplication(application)
|
|
@ -31,7 +31,7 @@ DAEMON_ARGS="--pid $PIDFILE \
|
|||
--workers=1 \
|
||||
--worker-class=sync \
|
||||
--timeout=60 \
|
||||
debian_wsgi:application"
|
||||
wcsinst.wsgi:application"
|
||||
|
||||
export PYTHONPATH=/usr/lib/$NAME
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade pylint
|
||||
pip install --upgrade -v -r requirements.txt
|
||||
echo Nothing to test for now
|
||||
(pylint -f parseable --rcfile /var/lib/jenkins/pylint.django.rc wcsinst/ | tee pylint.out) || /bin/true
|
10
manage.py
10
manage.py
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wcsinst.settings")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
execute_from_command_line(sys.argv)
|
|
@ -1,3 +0,0 @@
|
|||
django < 1.6
|
||||
south>=0.8,<0.9
|
||||
http://pypi.python.org/packages/source/d/django-jsonresponse/django-jsonresponse-0.5.tar.gz
|
33
setup.py
33
setup.py
|
@ -1,33 +0,0 @@
|
|||
#! /usr/bin/python
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
VERSION='0.1'
|
||||
|
||||
def get_version():
|
||||
if os.path.exists('.git'):
|
||||
p = subprocess.Popen(['git','describe','--dirty'], stdout=subprocess.PIPE)
|
||||
result = p.communicate()[0]
|
||||
return result.split()[0].replace('-','.')
|
||||
return VERSION
|
||||
|
||||
setup(name='wcsinst',
|
||||
version=get_version(),
|
||||
license='AGPLv3',
|
||||
description='',
|
||||
url='https://dev.entrouvert.org/projects/wcsinst/',
|
||||
download_url='http://repos.entrouvert.org/wcsinst.git/',
|
||||
author="Entr'ouvert",
|
||||
author_email="info@entrouvert.com",
|
||||
packages=find_packages(os.path.dirname(__file__) or '.'),
|
||||
scripts=['manage.py'],
|
||||
include_package_data = True,
|
||||
install_requires=[
|
||||
'django >= 1.5.1, < 1.6',
|
||||
],
|
||||
dependency_links = [
|
||||
'http://pypi.python.org/packages/source/d/django-jsonresponse/django-jsonresponse-0.5.tar.gz',
|
||||
],
|
||||
)
|
|
@ -1,163 +0,0 @@
|
|||
# Django settings for wcsinst project.
|
||||
|
||||
import os
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
PROJECT_PATH = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@example.com'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(PROJECT_PATH, 'wcsinst.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
# Hosts/domain names that are valid for this site; required if DEBUG is False
|
||||
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# In a Windows environment this must be set to your system time zone.
|
||||
TIME_ZONE = 'Europe/Brussels'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'fr-fr'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale.
|
||||
USE_L10N = True
|
||||
|
||||
# If you set this to False, Django will not use timezone-aware datetimes.
|
||||
USE_TZ = True
|
||||
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
# Example: "/var/www/example.com/media/"
|
||||
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://example.com/media/", "http://media.example.com/"
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
# Absolute path to the directory static files should be collected to.
|
||||
# Don't put anything in this directory yourself; store your static files
|
||||
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
|
||||
# Example: "/var/www/example.com/static/"
|
||||
STATIC_ROOT = os.path.join(PROJECT_PATH, 'static')
|
||||
|
||||
# URL prefix for static files.
|
||||
# Example: "http://example.com/static/", "http://static.example.com/"
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Additional locations of static files
|
||||
STATICFILES_DIRS = (
|
||||
os.path.join(PROJECT_PATH, 'wcsinst', 'static'),
|
||||
)
|
||||
|
||||
# List of finder classes that know how to find static files in
|
||||
# various locations.
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||
)
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = 'sw-v(^psaet3)44flti-zr!=u64mzfeaodkey(m=&^nz(=43!o'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
# Uncomment the next line for simple clickjacking protection:
|
||||
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'wcsinst.urls'
|
||||
|
||||
# Python dotted path to the WSGI application used by Django's runserver.
|
||||
WSGI_APPLICATION = 'wcsinst.wsgi.application'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
os.path.join(PROJECT_PATH, 'wcsinst', 'templates'),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'south',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.admin',
|
||||
)
|
||||
|
||||
# A sample logging configuration. The only tangible logging
|
||||
# performed by this configuration is to send an email to
|
||||
# the site admins on every HTTP 500 error when DEBUG=False.
|
||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
||||
# more details on how to customize your logging configuration.
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'filters': {
|
||||
'require_debug_false': {
|
||||
'()': 'django.utils.log.RequireDebugFalse'
|
||||
}
|
||||
},
|
||||
'handlers': {
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'filters': ['require_debug_false'],
|
||||
'class': 'django.utils.log.AdminEmailHandler'
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
'django.request': {
|
||||
'handlers': ['mail_admins'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
WCSINSTD_URL = os.environ.get('WCSINSTD_URL')
|
||||
|
||||
if WCSINSTD_URL:
|
||||
INSTALLED_APPS += ('wcsinst.wcsinst',)
|
||||
else:
|
||||
INSTALLED_APPS += ('wcsinst.wcsinstd',)
|
||||
|
||||
WCSINST_WCSCTL_SCRIPT = os.environ.get('WCSINST_WCSCTL_SCRIPT', 'wcsctl')
|
||||
|
||||
try:
|
||||
from local_settings import *
|
||||
except ImportError:
|
||||
pass
|
|
@ -1,13 +0,0 @@
|
|||
from django.conf.urls import patterns, include, url
|
||||
from django.conf import settings
|
||||
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
|
||||
if 'wcsinst.wcsinstd' in settings.INSTALLED_APPS:
|
||||
urlpatterns += patterns('',
|
||||
(r'^wcsinstd/', include('wcsinst.wcsinstd.urls')))
|
|
@ -1,31 +0,0 @@
|
|||
from django.contrib import admin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from models import WcsInstance, ApiSecret, Variable
|
||||
|
||||
class ApiSecretsInline(admin.TabularInline):
|
||||
model = ApiSecret
|
||||
verbose_name = _('API secret')
|
||||
verbose_name_plural = _('API secrets')
|
||||
|
||||
class VariablesInline(admin.TabularInline):
|
||||
model = Variable
|
||||
verbose_name = _('variable')
|
||||
verbose_name_plural = _('variables')
|
||||
|
||||
class WcsInstanceAdmin(admin.ModelAdmin):
|
||||
prepopulated_fields = {'domain': ('title',)}
|
||||
fieldsets = (
|
||||
(None, {'fields': ('title', 'domain'),}),
|
||||
('site-options.cfg',
|
||||
{'fields': ('postgresql', ('saml2_use_role', 'saml2_role_prefix',), 'backoffice_feed_url' )}
|
||||
),
|
||||
('site-options.cfg au-quotidien',
|
||||
{'fields': ('drupal', 'ezldap', 'strongbox', 'clicrdv', 'domino' )}
|
||||
),
|
||||
)
|
||||
inlines = [VariablesInline, ApiSecretsInline]
|
||||
save_as = True
|
||||
|
||||
|
||||
admin.site.register(WcsInstance, WcsInstanceAdmin)
|
|
@ -1,34 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'WcsInstance'
|
||||
db.create_table(u'wcsinst_wcsinstance', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
|
||||
('domain', self.gf('django.db.models.fields.CharField')(max_length=100)),
|
||||
))
|
||||
db.send_create_signal(u'wcsinst', ['WcsInstance'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'WcsInstance'
|
||||
db.delete_table(u'wcsinst_wcsinstance')
|
||||
|
||||
|
||||
models = {
|
||||
u'wcsinst.wcsinstance': {
|
||||
'Meta': {'object_name': 'WcsInstance'},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['wcsinst']
|
|
@ -1,142 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'Variable'
|
||||
db.create_table(u'wcsinst_variable', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('key', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=1024, blank=True)),
|
||||
('wcs_instance', self.gf('django.db.models.fields.related.ForeignKey')(related_name='variables', to=orm['wcsinst.WcsInstance'])),
|
||||
))
|
||||
db.send_create_signal(u'wcsinst', ['Variable'])
|
||||
|
||||
# Adding model 'ApiSecret'
|
||||
db.create_table(u'wcsinst_apisecret', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('key', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=1024, blank=True)),
|
||||
('wcs_instance', self.gf('django.db.models.fields.related.ForeignKey')(related_name='api_secrets', to=orm['wcsinst.WcsInstance'])),
|
||||
))
|
||||
db.send_create_signal(u'wcsinst', ['ApiSecret'])
|
||||
|
||||
# Adding field 'WcsInstance.postgresql'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'postgresql',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.saml2_use_role'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'saml2_use_role',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.saml2_role_prefix'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'saml2_role_prefix',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=128, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.backoffice_feed_url'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'backoffice_feed_url',
|
||||
self.gf('django.db.models.fields.URLField')(default='', max_length=128, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.drupal'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'drupal',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.ezldap'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'ezldap',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.strongbox'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'strongbox',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.clicrdv'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'clicrdv',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'WcsInstance.domino'
|
||||
db.add_column(u'wcsinst_wcsinstance', 'domino',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Variable'
|
||||
db.delete_table(u'wcsinst_variable')
|
||||
|
||||
# Deleting model 'ApiSecret'
|
||||
db.delete_table(u'wcsinst_apisecret')
|
||||
|
||||
# Deleting field 'WcsInstance.postgresql'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'postgresql')
|
||||
|
||||
# Deleting field 'WcsInstance.saml2_use_role'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'saml2_use_role')
|
||||
|
||||
# Deleting field 'WcsInstance.saml2_role_prefix'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'saml2_role_prefix')
|
||||
|
||||
# Deleting field 'WcsInstance.backoffice_feed_url'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'backoffice_feed_url')
|
||||
|
||||
# Deleting field 'WcsInstance.drupal'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'drupal')
|
||||
|
||||
# Deleting field 'WcsInstance.ezldap'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'ezldap')
|
||||
|
||||
# Deleting field 'WcsInstance.strongbox'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'strongbox')
|
||||
|
||||
# Deleting field 'WcsInstance.clicrdv'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'clicrdv')
|
||||
|
||||
# Deleting field 'WcsInstance.domino'
|
||||
db.delete_column(u'wcsinst_wcsinstance', 'domino')
|
||||
|
||||
|
||||
models = {
|
||||
u'wcsinst.apisecret': {
|
||||
'Meta': {'object_name': 'ApiSecret'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'key': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
|
||||
'wcs_instance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'api_secrets'", 'to': u"orm['wcsinst.WcsInstance']"})
|
||||
},
|
||||
u'wcsinst.variable': {
|
||||
'Meta': {'object_name': 'Variable'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'key': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
|
||||
'wcs_instance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variables'", 'to': u"orm['wcsinst.WcsInstance']"})
|
||||
},
|
||||
u'wcsinst.wcsinstance': {
|
||||
'Meta': {'object_name': 'WcsInstance'},
|
||||
'backoffice_feed_url': ('django.db.models.fields.URLField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'clicrdv': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'domino': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'drupal': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'ezldap': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'postgresql': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'saml2_role_prefix': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'saml2_use_role': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'strongbox': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['wcsinst']
|
|
@ -1,117 +0,0 @@
|
|||
import json
|
||||
import logging
|
||||
import urllib2
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class WcsInstance(models.Model):
|
||||
title = models.CharField(max_length=50)
|
||||
domain = models.CharField(max_length=100)
|
||||
|
||||
# site-options.cfg options
|
||||
postgresql = models.BooleanField(verbose_name=_('postgresql'),
|
||||
blank=True)
|
||||
saml2_use_role = models.BooleanField(verbose_name=_('use saml2 roles'),
|
||||
blank=True)
|
||||
saml2_role_prefix = models.CharField(verbose_name=_('role prefix'),
|
||||
blank=True, max_length=128)
|
||||
backoffice_feed_url = models.URLField(verbose_name=_('backoffice feed url'),
|
||||
blank=True, max_length=128)
|
||||
drupal = models.BooleanField(verbose_name=_('drupal'),
|
||||
blank=True)
|
||||
ezldap = models.BooleanField(verbose_name=_('ezldap'),
|
||||
blank=True)
|
||||
strongbox = models.BooleanField(verbose_name=_('strongbox'),
|
||||
blank=True)
|
||||
clicrdv = models.BooleanField(verbose_name=_('clicrdv'),
|
||||
blank=True)
|
||||
domino = models.BooleanField(verbose_name=_('domino'),
|
||||
blank=True)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s (%s)' % (self.title, self.domain)
|
||||
|
||||
def site_options_cfg(self):
|
||||
d = {
|
||||
'postgresql': self.postgresql,
|
||||
'saml2_use_role': self.saml2_use_role,
|
||||
'saml2_role_prefix': self.saml2_role_prefix,
|
||||
'backoffice_feed_url': self.backoffice_feed_url,
|
||||
'drupal': self.drupal,
|
||||
'ezldap': self.ezldap,
|
||||
'strongbox': self.strongbox,
|
||||
'clicrdv': self.clicrdv,
|
||||
'domino': self.domino,
|
||||
}
|
||||
d['api_secrets'] = dict((kv.key, kv.value) for kv in self.api_secrets.all())
|
||||
d['variables'] = dict((kv.key, kv.value) for kv in self.variables.all())
|
||||
return d
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
'title': self.title,
|
||||
'domain': self.domain,
|
||||
'site_options_cfg': self.site_options_cfg(),
|
||||
}
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
created = (self.id is None)
|
||||
super(WcsInstance, self).save(*args, **kwargs)
|
||||
# notify wcsinstd
|
||||
if not settings.WCSINSTD_URL:
|
||||
return
|
||||
if created:
|
||||
url = settings.WCSINSTD_URL + 'wcsinstd/create'
|
||||
else:
|
||||
url = settings.WCSINSTD_URL + 'wcsinstd/%s/' % self.domain
|
||||
post_data = json.dumps(self.to_json())
|
||||
request = urllib2.Request(url)
|
||||
request.add_header('Accept', 'application/json')
|
||||
request.add_header('Content-Type', 'application/json;charset=UTF-8')
|
||||
request.add_data(post_data)
|
||||
try:
|
||||
p = urllib2.urlopen(request)
|
||||
except urllib2.HTTPError as e:
|
||||
logger.error('wcsinstd HTTP error (%s)', str(e))
|
||||
print e.read()
|
||||
except urllib2.URLError as e:
|
||||
print e
|
||||
logger.error('wcsinstd URL error (%s)', str(e))
|
||||
else:
|
||||
out_data = p.read()
|
||||
p.close()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('wcs instance')
|
||||
verbose_name_plural = _('wcs instances')
|
||||
|
||||
|
||||
class KeyValue(models.Model):
|
||||
key = models.CharField(max_length=128)
|
||||
value = models.CharField(max_length=1024, blank=True)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class Variable(KeyValue):
|
||||
wcs_instance = models.ForeignKey(WcsInstance, related_name='variables')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('variable')
|
||||
verbose_name_plural = _('variables')
|
||||
|
||||
|
||||
class ApiSecret(KeyValue):
|
||||
wcs_instance = models.ForeignKey(WcsInstance, related_name='api_secrets')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('api secret')
|
||||
verbose_name_plural = _('api secrets')
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
"""
|
||||
This file demonstrates writing tests using the unittest module. These will pass
|
||||
when you run "manage.py test".
|
||||
|
||||
Replace this with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.assertEqual(1 + 1, 2)
|
|
@ -1 +0,0 @@
|
|||
# Create your views here.
|
|
@ -1,5 +0,0 @@
|
|||
from django.conf import settings
|
||||
|
||||
URL_TEMPLATE = getattr(settings, 'WCSINST_URL_TEMPLATE', 'https://%(domain)s')
|
||||
WCS_APP_DIR = getattr(settings, 'WCSINST_WCS_APP_DIR', None)
|
||||
WCSCTL_SCRIPT = getattr(settings, 'WCSINST_WCSCTL_SCRIPT', 'wcsctl')
|
|
@ -1,226 +0,0 @@
|
|||
import string
|
||||
import cPickle
|
||||
import os
|
||||
import zipfile
|
||||
import subprocess
|
||||
from urlparse import urlparse
|
||||
|
||||
from cStringIO import StringIO
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
import psycopg2
|
||||
|
||||
from . import app_settings
|
||||
|
||||
|
||||
def get_provider_key(provider_id):
|
||||
return provider_id.replace('://', '-').replace('/', '-').replace('?', '-').replace(':', '-')
|
||||
|
||||
|
||||
class DeployInstance(object):
|
||||
skeleton = 'default'
|
||||
|
||||
skel_dir = None
|
||||
collectivity_install_dir = None
|
||||
|
||||
def __init__(self, domain, title, site_options_cfg):
|
||||
self.domain = domain
|
||||
self.title = title
|
||||
self.site_options_cfg = site_options_cfg
|
||||
|
||||
def make(self):
|
||||
self.skel_dir = os.path.join(settings.MEDIA_ROOT, 'skeletons', self.skeleton)
|
||||
|
||||
url_template = app_settings.URL_TEMPLATE
|
||||
self.url = str(url_template % {'domain': self.domain})
|
||||
|
||||
host, path = urlparse(self.url)[1:3]
|
||||
if path.endswith('/'):
|
||||
path = path[:-1]
|
||||
|
||||
coldir = host
|
||||
if path:
|
||||
coldir += path.replace('/', '+')
|
||||
|
||||
self.collectivity_install_dir = os.path.join(app_settings.WCS_APP_DIR, coldir)
|
||||
|
||||
if os.path.exists(self.collectivity_install_dir):
|
||||
# site exists, let's update it
|
||||
pass
|
||||
anew = False
|
||||
else:
|
||||
anew = True
|
||||
os.mkdir(self.collectivity_install_dir)
|
||||
|
||||
z = zipfile.ZipFile(os.path.join(self.skel_dir, 'export.wcs'), 'r')
|
||||
|
||||
for f in z.namelist():
|
||||
path = os.path.join(self.collectivity_install_dir, f)
|
||||
data = z.read(f)
|
||||
if not os.path.exists(os.path.dirname(path)):
|
||||
os.mkdir(os.path.dirname(path))
|
||||
open(path, 'w').write(data)
|
||||
z.close()
|
||||
|
||||
config_file = os.path.join(self.collectivity_install_dir, 'config.pck')
|
||||
if os.path.exists(config_file):
|
||||
wcs_cfg = cPickle.load(file(os.path.join(self.collectivity_install_dir, 'config.pck')))
|
||||
else:
|
||||
wcs_cfg = {}
|
||||
|
||||
has_sql = self.make_sql_config(wcs_cfg)
|
||||
self.make_sso_config(wcs_cfg)
|
||||
self.make_site_options()
|
||||
|
||||
cPickle.dump(wcs_cfg, file(config_file, 'w'))
|
||||
|
||||
if has_sql:
|
||||
self.make_sql_tables(wcs_cfg)
|
||||
|
||||
self.make_apache_vhost()
|
||||
self.reload_apache()
|
||||
|
||||
|
||||
def make_sql_config(self, wcs_cfg):
|
||||
if not wcs_cfg.get('postgresql'):
|
||||
# this is not a site configured to use SQL
|
||||
return False
|
||||
|
||||
database_name = wcs_cfg['postgresql'].get('database', 'wcs')
|
||||
domain_table_name = self.domain.replace('-', '_').replace('.', '_')
|
||||
if '_' in database_name:
|
||||
database_name = '%s_%s' % (database_name.split('_')[0], domain_table_name)
|
||||
else:
|
||||
database_name = '%s_%s' % (database_name, domain_table_name)
|
||||
|
||||
postgresql_cfg = {}
|
||||
for k, v in wcs_cfg['postgresql'].items():
|
||||
if v:
|
||||
postgresql_cfg[k] = v
|
||||
try:
|
||||
pgconn = psycopg2.connect(**postgresql_cfg)
|
||||
except psycopg2.Error:
|
||||
# XXX: log
|
||||
raise
|
||||
|
||||
pgconn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
|
||||
cur = pgconn.cursor()
|
||||
try:
|
||||
cur.execute('''CREATE DATABASE %s''' % database_name)
|
||||
except psycopg2.Error as e:
|
||||
print 'got psycopg2 error:', e
|
||||
cur.close()
|
||||
|
||||
wcs_cfg['postgresql']['database'] = database_name
|
||||
|
||||
return True
|
||||
|
||||
def make_sql_tables(self, wcs_cfg):
|
||||
params = []
|
||||
for param in ('database', 'user', 'password', 'host', 'port'):
|
||||
if wcs_cfg.get('postgresql').get(param):
|
||||
if param == 'database':
|
||||
params.append('--dbname')
|
||||
else:
|
||||
params.append('--' + param)
|
||||
params.append(wcs_cfg.get('postgresql').get(param))
|
||||
os.system('%s convert-to-sql %s %s' % (app_settings.WCSCTL_SCRIPT, ' '.join(params), self.domain))
|
||||
|
||||
def make_sso_config(self, wcs_cfg):
|
||||
has_idff = False
|
||||
has_saml2 = False
|
||||
|
||||
service_provider_configuration = {}
|
||||
|
||||
if self.url.endswith('/'):
|
||||
url_stripped = self.url[:-1]
|
||||
else:
|
||||
url_stripped = self.url
|
||||
|
||||
if os.path.exists(os.path.join(self.skel_dir, 'idff-metadata-template')):
|
||||
# there's a ID-FF metadata template, so we do the ID-FF stuff
|
||||
has_idff = True
|
||||
service_provider_configuration.update({
|
||||
'base_url': '%s/liberty' % url_stripped,
|
||||
'metadata': 'metadata.xml',
|
||||
'providerid': '%s/liberty/metadata' % url_stripped,
|
||||
})
|
||||
|
||||
idff_metadata_template = file(
|
||||
os.path.join(self.skel_dir, 'idff-metadata-template')).read()
|
||||
file(os.path.join(self.collectivity_install_dir, 'metadata.xml'), 'w').write(
|
||||
string.Template(idff_metadata_template).substitute({'url': url_stripped}))
|
||||
|
||||
if os.path.exists(os.path.join(self.skel_dir, 'saml2-metadata-template')):
|
||||
# there's a SAMLv2 metadata template, so we do the SAMLv2 stuff
|
||||
has_saml2 = True
|
||||
service_provider_configuration.update({
|
||||
'saml2_base_url': '%s/saml' % url_stripped,
|
||||
'saml2_metadata': 'saml2-metadata.xml',
|
||||
'saml2_providerid': '%s/saml/metadata' % url_stripped
|
||||
})
|
||||
|
||||
saml2_metadata_template = file(
|
||||
os.path.join(self.skel_dir, 'saml2-metadata-template')).read()
|
||||
file(os.path.join(self.collectivity_install_dir, 'saml2-metadata.xml'), 'w').write(
|
||||
string.Template(saml2_metadata_template).substitute({'url': url_stripped}))
|
||||
|
||||
if has_idff or has_saml2:
|
||||
idp_metadata = ET.parse(file(os.path.join(self.skel_dir, 'idp-metadata.xml')))
|
||||
entity_id = idp_metadata.getroot().attrib['entityID']
|
||||
idp_key = get_provider_key(entity_id)
|
||||
|
||||
wcs_cfg['identification'] = {'methods': ['idp']}
|
||||
wcs_cfg['idp'] = {
|
||||
idp_key: {
|
||||
'metadata': 'provider-%s-metadata.xml' % idp_key,
|
||||
'metadata_url': entity_id,
|
||||
'publickey_url': None,
|
||||
'role': 2}}
|
||||
wcs_cfg['sp'] = {
|
||||
'common_domain': None,
|
||||
'common_domain_getter_url': None,
|
||||
'organization_name': self.title.encode('utf-8'),
|
||||
'privatekey': 'private-key.pem',
|
||||
'publickey': 'public-key.pem'}
|
||||
wcs_cfg['sp'].update(service_provider_configuration)
|
||||
|
||||
file(os.path.join(self.collectivity_install_dir, 'provider-%s-metadata.xml' % idp_key), 'w').write(
|
||||
file(os.path.join(self.skel_dir, 'idp-metadata.xml')).read())
|
||||
file(os.path.join(self.collectivity_install_dir, 'public-key.pem'), 'w').write(
|
||||
file(os.path.join(self.skel_dir, 'public-key.pem')).read())
|
||||
file(os.path.join(self.collectivity_install_dir, 'private-key.pem'), 'w').write(
|
||||
file(os.path.join(self.skel_dir, 'private-key.pem')).read())
|
||||
else:
|
||||
wcs_cfg['identification'] = {'methods': ['password']}
|
||||
|
||||
|
||||
def make_site_options(self):
|
||||
options_template_path = os.path.join(self.skel_dir, 'site-options.cfg')
|
||||
if not os.path.exists(options_template_path):
|
||||
return
|
||||
options_template = file(options_template_path).read()
|
||||
file(os.path.join(self.collectivity_install_dir, 'site-options.cfg'), 'w').write(
|
||||
string.Template(options_template).substitute({
|
||||
'domain': self.domain,
|
||||
'options': self.site_options_cfg
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
def make_apache_vhost(self):
|
||||
apache_vhost_template_path = os.path.join(self.skel_dir, 'apache-vhost.conf')
|
||||
if not os.path.exists(apache_vhost_template_path):
|
||||
return
|
||||
apache_vhost_template = file(apache_vhost_template_path).read()
|
||||
apache_dir = os.path.join(settings.MEDIA_ROOT, 'vhosts.d')
|
||||
if not os.path.exists(apache_dir):
|
||||
os.mkdir(apache_dir)
|
||||
file(os.path.join(apache_dir, '%s.conf' % self.domain), 'w').write(
|
||||
string.Template(apache_vhost_template).substitute({'domain': self.domain}))
|
||||
|
||||
|
||||
def reload_apache(self):
|
||||
os.system('sudo -n /etc/init.d/apache2 reload')
|
|
@ -1,3 +0,0 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
|
@ -1,7 +0,0 @@
|
|||
from django.conf.urls import patterns, url, include
|
||||
|
||||
urlpatterns = patterns('wcsinst.wcsinstd.views',
|
||||
url(r'^create$', 'create'),
|
||||
url(r'^(?P<instance>[\w\.-]+)/$', 'update'),
|
||||
)
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
import json
|
||||
import threading
|
||||
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from jsonresponse import to_json
|
||||
|
||||
from .deploy import DeployInstance
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@to_json('api')
|
||||
@require_POST
|
||||
def create(request):
|
||||
data = json.loads(request.body)
|
||||
deploy = DeployInstance(**data)
|
||||
threading.Thread(target=deploy.make).start()
|
||||
return {}
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@to_json('api')
|
||||
@require_POST
|
||||
def update(request, instance):
|
||||
print 'updating instance:', instance
|
||||
data = json.loads(request.body)
|
||||
if data.get('domain') != instance:
|
||||
raise Exception('domain mismatch') # -> should remove/add ?
|
||||
deploy = DeployInstance(**data)
|
||||
threading.Thread(target=deploy.make).start()
|
||||
return {}
|
|
@ -1,32 +0,0 @@
|
|||
"""
|
||||
WSGI config for wcsinst project.
|
||||
|
||||
This module contains the WSGI application used by Django's development server
|
||||
and any production WSGI deployments. It should expose a module-level variable
|
||||
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
|
||||
this application via the ``WSGI_APPLICATION`` setting.
|
||||
|
||||
Usually you will have the standard Django WSGI application here, but it also
|
||||
might make sense to replace the whole Django WSGI application with a custom one
|
||||
that later delegates to the Django one. For example, you could introduce WSGI
|
||||
middleware here, or combine a Django application with an application of another
|
||||
framework.
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
||||
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
||||
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
||||
# os.environ["DJANGO_SETTINGS_MODULE"] = "wcsinst.settings"
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wcsinst.settings")
|
||||
|
||||
# This application object is used by any WSGI server configured to use this
|
||||
# file. This includes Django's development server, if the WSGI_APPLICATION
|
||||
# setting points here.
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
|
||||
# Apply WSGI middleware here.
|
||||
# from helloworld.wsgi import HelloWorldApplication
|
||||
# application = HelloWorldApplication(application)
|
Reference in New Issue