diff --git a/INSTALL.md b/INSTALL.md index ee4654d6..1c928779 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -43,9 +43,8 @@ Django-orchestra can be installed on any Linux system, however it is **strongly python3 manage.py migrate ``` - 6. Configure periodic execution of tasks (choose one) - 1. Use cron + 1. Use cron (recommended) ```bash python3 manage.py setupcronbeat python3 manage.py syncperiodictasks @@ -98,7 +97,6 @@ python3 manage.py orchestraversion ``` - Extra ===== diff --git a/ROADMAP.md b/ROADMAP.md index 79696313..9ae4e66b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,48 +3,6 @@ Note `*` _for sustancial progress_ -### 2.0 Milestone (unscheduled) - -1. [ ] Integration with third-party service providers, e.g. Gandi -2. [ ] Scheduling of service cancellations and deactivations -1. [ ] Object-level permission system -2. [ ] REST API functionality for superusers -3. [ ] Responsive user interface, based on a JS framework. -4. [ ] Full development documentation -5. [ ] [Ansible](http://www.ansible.com/home) orchestration method, which synchronizes the whole service config everytime instead of incremental changes. - - -### 1.0 Milestone (first stable release on Sep '15) - -1. [ ] Stabilize data model, internal APIs and REST API -3. [ ] Spanish and Catalan translations -1. [ ] Complete documentation for developers - - -### 1.0b1 Milestone (first beta release on ~~Dec '14~~ Jun '15) - -1. [x] Resource allocation and monitoring -1. [x] Order tracking -2. [x] Service definition framework, service plans and pricing -3. [ ] *Billing - 3. [x] Invoice - 3. [x] Membership fee - 3. [ ] *Amendment invoice - 3. [ ] *Amendment fee - 3. [x] Pro Forma - 3. [ ] *Advanced bill handling (move lines, undo billing, ...) -1. [x] Payment methods - 1. [x] SEPA Direct Debit - 2. [x] SEPA Credit Transfer -2. [ ] *Additional services - 2. [ ] *VPS with Proxmox/OpenVZ - 2. [ ] *SaaS (Software as a Service) Redmine/phpList/BSCW/Wordpress/Moodle/Drupal - 2. [ ] *Wordpress/Python webapps - 2. [x] Miscellaneous services -2. [x] Issue tracking system - - - ### 1.0a1 Milestone (first alpha release on ~~Oct '14~~ Apr '15) 1. [x] Automated deployment of the development environment @@ -69,4 +27,43 @@ Note `*` _for sustancial progress_ 1. [ ] Initial documentation +### 1.0b1 Milestone (first beta release on ~~Dec '14~~ Jun '15) +1. [x] Resource allocation and monitoring +1. [x] Order tracking +2. [x] Service definition framework, service plans and pricing +3. [ ] *Billing + 3. [x] Invoice + 3. [x] Membership fee + 3. [x] Amendment invoice + 3. [x] Amendment fee + 3. [x] Pro Forma + 3. [ ] *Advanced bill handling (move lines, undo billing, ...) +1. [x] Payment methods + 1. [x] SEPA Direct Debit + 2. [x] SEPA Credit Transfer +2. [ ] Additional services + 2. [ ] *VPS with Proxmox/OpenVZ + 2. [x] SaaS (Software as a Service) Gitlab/phpList/BSCW/Wordpress/Moodle/Drupal + 2. [x] Wordpress webapps + 3. [ ] uwsgi-emperor Python webapps + 2. [x] Miscellaneous services +2. [x] Issue tracking system + + +### 1.0 Milestone (first stable release on Sep '15) + +1. [ ] Stabilize data model, internal APIs and REST API +3. [ ] Spanish and Catalan translations +1. [ ] Complete documentation for developers + + +### 2.0 Milestone (unscheduled) + +1. [ ] Integration with third-party service providers, e.g. Gandi +2. [ ] Scheduling of service cancellations and deactivations +1. [ ] Object-level permission system +2. [ ] REST API functionality for superusers +3. [ ] Responsive user interface, based on a JS framework. +4. [ ] Full development documentation +5. [ ] [Ansible](http://www.ansible.com/home) orchestration method, which synchronizes the whole service config everytime instead of incremental changes. diff --git a/orchestra/contrib/saas/settings.py b/orchestra/contrib/saas/settings.py index 395064dd..2a5460d1 100644 --- a/orchestra/contrib/saas/settings.py +++ b/orchestra/contrib/saas/settings.py @@ -4,6 +4,7 @@ from orchestra.contrib.settings import Setting from orchestra.core.validators import validate_ip_address from orchestra.settings import ORCHESTRA_BASE_DOMAIN +from . import validators from .. import saas @@ -36,6 +37,7 @@ SAAS_TRAFFIC_IGNORE_HOSTS = Setting('SAAS_TRAFFIC_IGNORE_HOSTS', SAAS_WORDPRESS_ALLOW_CUSTOM_URL = Setting('SAAS_WORDPRESS_ALLOW_CUSTOM_URL', True, help_text=_("Whether allow custom URL to be specified or not."), + validators=[validators.validate_website_saas_directives('wordpress-saas')], ) SAAS_WORDPRESS_LOG_PATH = Setting('SAAS_WORDPRESS_LOG_PATH', @@ -68,6 +70,7 @@ SAAS_WORDPRESS_DB_NAME = Setting('SAAS_WORDPRESS_DB_NAME', SAAS_DOKUWIKI_ALLOW_CUSTOM_URL = Setting('SAAS_DOKUWIKI_ALLOW_CUSTOM_URL', True, help_text=_("Whether allow custom URL to be specified or not."), + validators=[validators.validate_website_saas_directives('dokuwiki-saas')], ) SAAS_DOKUWIKI_TEMPLATE_PATH = Setting('SAAS_DOKUWIKI_TEMPLATE_PATH', @@ -108,6 +111,7 @@ SAAS_DOKUWIKI_LOG_PATH = Setting('SAAS_DOKUWIKI_LOG_PATH', SAAS_DRUPAL_ALLOW_CUSTOM_URL = Setting('SAAS_DRUPAL_ALLOW_CUSTOM_URL', True, help_text=_("Whether allow custom URL to be specified or not."), + validators=[validators.validate_website_saas_directives('drupal-saas')], ) SAAS_DRUPAL_SITES_PATH = Setting('WEBSITES_DRUPAL_SITES_PATH', @@ -120,6 +124,7 @@ SAAS_DRUPAL_SITES_PATH = Setting('WEBSITES_DRUPAL_SITES_PATH', SAAS_PHPLIST_ALLOW_CUSTOM_URL = Setting('SAAS_PHPLIST_ALLOW_CUSTOM_URL', False, help_text=_("Whether allow custom URL to be specified or not."), + validators=[validators.validate_website_saas_directives('phplist-saas')], ) SAAS_PHPLIST_DB_USER = Setting('SAAS_PHPLIST_DB_USER', @@ -229,6 +234,7 @@ SAAS_GITLAB_DOMAIN = Setting('SAAS_GITLAB_DOMAIN', SAAS_MOODLE_ALLOW_CUSTOM_URL = Setting('SAAS_MOODLE_ALLOW_CUSTOM_URL', True, help_text=_("Whether allow custom URL to be specified or not."), + validators=[validators.validate_website_saas_directives('moodle-saas')], ) SAAS_MOODLE_DB_USER = Setting('SAAS_MOODLE_DB_USER', diff --git a/orchestra/contrib/settings/__init__.py b/orchestra/contrib/settings/__init__.py index da705064..75dc91cd 100644 --- a/orchestra/contrib/settings/__init__.py +++ b/orchestra/contrib/settings/__init__.py @@ -82,16 +82,16 @@ class Setting(object): raise ValidationError(errors) return validate_string_format - def validate_value(self, value): - if value: - validators.all_valid(value, self.validators) + def validate(self): + if self.value: + validators.all_valid(self.value, self.validators) valid_types = list(self.types) if isinstance(self.default, (list, tuple)): valid_types.extend([list, tuple]) valid_types.append(type(self.default)) - if not isinstance(value, tuple(valid_types)): + if not isinstance(self.value, tuple(valid_types)): raise ValidationError("%s is not a valid type (%s)." % - (type(value).__name__, ', '.join(t.__name__ for t in valid_types)) + (type(self.value).__name__, ', '.join(t.__name__ for t in valid_types)) ) @classmethod diff --git a/orchestra/contrib/settings/apps.py b/orchestra/contrib/settings/apps.py index 2cc94bda..17fa85c6 100644 --- a/orchestra/contrib/settings/apps.py +++ b/orchestra/contrib/settings/apps.py @@ -23,8 +23,8 @@ class SettingsConfig(AppConfig): messages = [] for name, setting in Setting.settings.items(): try: - setting.validate_value(setting.value) + setting.validate() except ValidationError as exc: - msg = "Error validating setting with value %s: %s" % (setting.value, str(exc)) + msg = "Error validating setting with value %s: %s" % (setting.value, exc) messages.append(Error(msg, obj=name, id='settings.E001')) return messages diff --git a/orchestra/contrib/systemusers/backends.py b/orchestra/contrib/systemusers/backends.py index 3d41f6d4..ce510c98 100644 --- a/orchestra/contrib/systemusers/backends.py +++ b/orchestra/contrib/systemusers/backends.py @@ -31,7 +31,6 @@ class UNIXUserBackend(ServiceController): groups = ','.join(self.get_groups(user)) context['groups_arg'] = '--groups %s' % groups if groups else '' # TODO userd add will fail if %(user)s group already exists - # TODO mkhomedir_helper self.append(textwrap.dedent(""" # Update/create user state for %(user)s if id %(user)s ; then @@ -56,13 +55,19 @@ class UNIXUserBackend(ServiceController): fi mkdir -p %(base_home)s chmod 750 %(base_home)s - chown %(user)s:%(user)s %(base_home)s""") % context + ls -A /etc/skel/ | while read line; do + if [[ ! -e %(home)s/${line} ]]; then + cp -a $line %(home)s/${line} + chown -R %(user)s:%(group)s %(home)s/${line} + fi + done + """) % context ) if context['home'] != context['base_home']: self.append(textwrap.dedent(""" # Set extra permissions: %(user)s home is inside %(mainuser)s home if mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl > /dev/null; then - # Accountn group as the owner + # Account group as the owner chown %(mainuser)s:%(mainuser)s %(home)s chmod g+s %(home)s # Home access @@ -76,6 +81,8 @@ class UNIXUserBackend(ServiceController): chown %(user)s:%(user)s %(home)s fi""") % context ) + else: + self.append("chown %(user)s:%(group)s %(home)s" % context) for member in settings.SYSTEMUSERS_DEFAULT_GROUP_MEMBERS: context['member'] = member self.append('usermod -a -G %(user)s %(member)s || exit_code=$?' % context) diff --git a/orchestra/management/commands/setupcronbeat.py b/orchestra/management/commands/setupcronbeat.py index 0ff974c8..1bb423f5 100644 --- a/orchestra/management/commands/setupcronbeat.py +++ b/orchestra/management/commands/setupcronbeat.py @@ -26,7 +26,7 @@ class Command(BaseCommand): context['content'] = content run("cat << EOF | crontab\n%(content)s\nEOF" % context, display=True) - # Configrue settings to use threaded task backend + # Configrue settings to use threaded task backend (default) changes = {} if Setting.settings['TASKS_BACKEND'].value == 'celery': changes['TASKS_BACKEND'] = settings_parser.Remove() diff --git a/requirements.txt b/requirements.txt index ac887909..d1d79229 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -django==1.8.2 +django==1.8.4 django-fluent-dashboard==0.5.3 django-admin-tools==0.6.0 django-extensions==1.5.2 diff --git a/scripts/containers/deploy.sh b/scripts/containers/deploy.sh index cadb1e1d..1bb16eab 100644 --- a/scripts/containers/deploy.sh +++ b/scripts/containers/deploy.sh @@ -44,7 +44,7 @@ function install_orchestra () { home=$2 repo=$3 - if [[ $dev -eq 1 ]]; then + if [[ $dev ]]; then # Install from source python_path=$(python3 -c "import sys; print([path for path in sys.path if path.startswith('/usr/local/lib/python')][0]);") if [[ -d $python_path/orchestra ]]; then @@ -80,7 +80,7 @@ function setup_database () { dev=$1 noinput=$2 # Setup Database - if [[ $dev -eq 1 ]]; then + if [[ $dev ]]; then # Speeding up tests, don't do this in production! . /usr/share/postgresql-common/init.d-functions pg_version=$(psql --version | head -n1 | sed -r "s/^.*\s([0-9]+\.[0-9]+).*/\1/") @@ -96,7 +96,7 @@ function setup_database () { else run sudo python3 -W ignore manage.py setuppostgres fi - if [[ $dev -eq 1 ]]; then + if [[ $dev ]]; then # Create database permissions are needed for running tests sudo su postgres -c 'psql -c "ALTER USER orchestra CREATEDB;"' fi @@ -166,19 +166,19 @@ function main () { opts=$(getopt -o n:dr:h -l noinput:,dev,repo:,help -- "$@") || exit 1 set -- $opts - dev=0 - noinput='' + dev= + noinput= user=${USER:-root} repo='https://github.com/glic3rinu/django-orchestra.git' - brepo=false + brepo= project_name="panel" - bproject_name=false + bproject_name= while [ $# -gt 0 ]; do case $1 in -n|--noinput) user="${2:1:${#2}-2}"; noinput='--noinput'; shift ;; -r|--repo) repo="${2:1:${#2}-2}"; brepo=true; shift ;; - -d|--dev) dev=1; ;; + -d|--dev) dev=true; ;; -p|--project_name) project_name="${2:1:${#2}-2}"; bproject_name=true; shift ;; -h|--help) print_help; exit 0 ;; (--) shift; break;; @@ -208,12 +208,12 @@ function main () { run () { echo " ${bold}\$ ${@}${normal}"; ${@}; } surun () { echo " ${bold}\$ su $user -c \"${@}\"${normal}"; su $user -c "${@}"; } fi - if [[ $dev -eq 0 && $brepo == true ]]; then + if [[ ! $dev && $brepo ]]; then echo -e "\nErr. --repo only makes sense with --dev\n" >&2 exit 5 fi - if [[ ! $noinput && $bproject_name == false ]]; then + if [[ ! $noinput && ! $bproject_name ]]; then while true; do read -p "Enter a project name [panel]: " project_name if [[ ! "$project_name" ]]; then @@ -248,10 +248,10 @@ function main () { home=$(eval echo ~$user) cd $home - install_orchestra $dev $home $repo + install_orchestra "$dev" $home $repo surun "orchestra-admin startproject $project_name" cd $project_name - setup_database $dev "$noinput" + setup_database "$dev" "$noinput" if [[ $noinput ]]; then create_orchestra_superuser $user $user@localhost orchestra @@ -281,7 +281,7 @@ function main () { fi # Configure settings file into debug mode - if [[ $dev -eq 1 ]]; then + if [[ $dev ]]; then sed -i \ -e "s/^\s*#\s*'debug_toolbar',/ 'debug_toolbar',/" \ -e "s/^\s*#\s*'django_nose',/ 'django_nose',/" $project_name/settings.py