diff --git a/.gitignore b/.gitignore index b4ca8763..0bca9ea5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ .svn local_settings.py build +*.egg-info diff --git a/README.md b/README.md index ac162b6e..c3c19293 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,30 @@ If you are planing to do some development or perhaps just checking out this proj sudo ~orchestra/django-orchestra/scripts/container/deploy.sh ``` +Fast Deployment Setup +--------------------- +To only run the python interface follow this steps: + +1. python3 -menv env-django-orchestra +2. source env-django-orchestra/bin/activate +3. echo $HOME/django-orchestra/ | sudo tee env-django-orchestra/lib/python*/site-packages/orchestra.pth +4. pip3 install -r $HOME/django-orchestra/requirements.txt +5. django-admin.py startproject panel --template="$HOME/django-orchestra/orchestra/conf/project_template" +6. python3 panel/manage.py migrate accounts +7. python3 panel/manage.py migrate +8. # Create orchestra superuser + +cat <<- EOF | python3 panel/manage.py shell +from orchestra.contrib.accounts.models import Account +if not Account.objects.filter(username="admin").exists(): +print('Creating orchestra superuser') +Account.objects.create_superuser("admin", "admin@localhost", "orchestra") +EOF + +9. python3 panel/manage.py runserver +10. open http://localhost:8000/admin + +None of the services will work but you can see the web interface License ------- diff --git a/orchestra/admin/utils.py b/orchestra/admin/utils.py index 1237f349..b6e16e0f 100644 --- a/orchestra/admin/utils.py +++ b/orchestra/admin/utils.py @@ -8,7 +8,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.db import models from django.shortcuts import redirect -from django.utils import importlib +import importlib from django.utils.html import escape from django.utils.safestring import mark_safe diff --git a/orchestra/contrib/accounts/admin.py b/orchestra/contrib/accounts/admin.py index 8f96b9e4..6a385ebf 100644 --- a/orchestra/contrib/accounts/admin.py +++ b/orchestra/contrib/accounts/admin.py @@ -5,7 +5,7 @@ from urllib.parse import parse_qsl from django import forms from django.conf.urls import patterns, url from django.contrib import admin, messages -from django.contrib.admin.util import unquote +from django.contrib.admin.utils import unquote from django.contrib.auth import admin as auth from django.http import HttpResponseRedirect from django.utils.safestring import mark_safe diff --git a/orchestra/contrib/accounts/forms.py b/orchestra/contrib/accounts/forms.py index 104af327..df9a6803 100644 --- a/orchestra/contrib/accounts/forms.py +++ b/orchestra/contrib/accounts/forms.py @@ -2,7 +2,7 @@ from collections import OrderedDict from django import forms from django.core.exceptions import ValidationError -from django.db.models.loading import get_model +from django.apps import apps from django.utils.translation import ugettext_lazy as _ from orchestra.forms import UserCreationForm @@ -19,7 +19,7 @@ def create_account_creation_form(): "Notice that a related system user will be always created.")) }) for model, __, kwargs, help_text in settings.ACCOUNTS_CREATE_RELATED: - model = get_model(model) + model = apps.get_model(model) field_name = 'create_%s' % model._meta.model_name label = _("Create %s") % model._meta.verbose_name fields[field_name] = forms.BooleanField(initial=True, required=False, label=label, @@ -41,7 +41,7 @@ def create_account_creation_form(): if systemuser_model.objects.filter(username=account.username).exists(): errors['username'] = _("A system user with this name already exists.") for model, key, related_kwargs, __ in settings.ACCOUNTS_CREATE_RELATED: - model = get_model(model) + model = apps.get_model(model) kwargs = { key: eval(related_kwargs[key], {'account': account}) } @@ -59,7 +59,7 @@ def create_account_creation_form(): def save_related(self, account): for model, key, related_kwargs, __ in settings.ACCOUNTS_CREATE_RELATED: - model = get_model(model) + model = apps.get_model(model) field_name = 'create_%s' % model._meta.model_name if self.cleaned_data[field_name]: kwargs = { diff --git a/orchestra/contrib/accounts/models.py b/orchestra/contrib/accounts/models.py index c3b4128c..3ba10b56 100644 --- a/orchestra/contrib/accounts/models.py +++ b/orchestra/contrib/accounts/models.py @@ -1,7 +1,7 @@ from django.contrib.auth import models as auth from django.core import validators from django.db import models -from django.db.models.loading import get_model +from django.apps import apps from django.utils import timezone from django.utils.translation import ugettext_lazy as _ @@ -146,7 +146,7 @@ class Account(auth.AbstractBaseUser): for model, key, related_kwargs, __ in settings.ACCOUNTS_CREATE_RELATED: if 'password' not in related_kwargs: continue - model = get_model(model) + model = apps.get_model(model) kwargs = { key: eval(related_kwargs[key], {'account': self}) } diff --git a/orchestra/contrib/orchestration/management/commands/orchestrate.py b/orchestra/contrib/orchestration/management/commands/orchestrate.py index ccaf1a28..87aa1974 100644 --- a/orchestra/contrib/orchestration/management/commands/orchestrate.py +++ b/orchestra/contrib/orchestration/management/commands/orchestrate.py @@ -1,5 +1,5 @@ from django.core.management.base import BaseCommand, CommandError -from django.db.models.loading import get_model +from django.apps import apps from orchestra.contrib.orchestration import manager, Operation from orchestra.contrib.orchestration.models import Server @@ -34,7 +34,7 @@ class Command(BaseCommand): for backend in ServiceBackend.get_backends(): self.stdout.write(str(backend).split("'")[1]) return - model = get_model(*options['model'].split('.')) + model = apps.get_model(*options['model'].split('.')) action = options.get('action') interactive = options.get('interactive') servers = options.get('servers') diff --git a/orchestra/contrib/orchestration/models.py b/orchestra/contrib/orchestration/models.py index 435d233c..fbc90b68 100644 --- a/orchestra/contrib/orchestration/models.py +++ b/orchestra/contrib/orchestration/models.py @@ -1,6 +1,6 @@ import socket -from django.contrib.contenttypes import generic +from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.functional import cached_property @@ -104,7 +104,7 @@ class BackendOperation(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() - instance = generic.GenericForeignKey('content_type', 'object_id') + instance = GenericForeignKey('content_type', 'object_id') class Meta: verbose_name = _("Operation") diff --git a/orchestra/contrib/orders/models.py b/orchestra/contrib/orders/models.py index cbd15ddc..87652add 100644 --- a/orchestra/contrib/orders/models.py +++ b/orchestra/contrib/orders/models.py @@ -4,10 +4,10 @@ import logging from django.db import models from django.db.models import F, Q -from django.db.models.loading import get_model +from django.apps import apps from django.db.models.signals import post_delete, post_save, pre_delete from django.dispatch import receiver -from django.contrib.contenttypes import generic +from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.utils import timezone from django.utils.translation import ugettext_lazy as _ @@ -61,7 +61,7 @@ class OrderQuerySet(models.QuerySet): def get_related(self, **options): """ returns related orders that could have a pricing effect """ - Service = get_model(settings.ORDERS_SERVICE_MODEL) + Service = apps.get_model(settings.ORDERS_SERVICE_MODEL) conflictive = self.filter(service__metric='') conflictive = conflictive.exclude(service__billing_period=Service.NEVER) conflictive = conflictive.select_related('service').group_by('account_id', 'service') @@ -122,7 +122,7 @@ class Order(models.Model): ignore = models.BooleanField(_("ignore"), default=False) description = models.TextField(_("description"), blank=True) - content_object = generic.GenericForeignKey() + content_object = GenericForeignKey() objects = OrderQuerySet.as_manager() class Meta: @@ -135,7 +135,7 @@ class Order(models.Model): def update_orders(cls, instance, service=None, commit=True): updates = [] if service is None: - Service = get_model(settings.ORDERS_SERVICE_MODEL) + Service = apps.get_model(settings.ORDERS_SERVICE_MODEL) services = Service.get_services(instance) else: services = [service] diff --git a/orchestra/contrib/resources/admin.py b/orchestra/contrib/resources/admin.py index f8470c00..e3a090de 100644 --- a/orchestra/contrib/resources/admin.py +++ b/orchestra/contrib/resources/admin.py @@ -1,7 +1,7 @@ from django.conf.urls import patterns, url from django.contrib import admin, messages from django.contrib.admin.utils import unquote -from django.contrib.contenttypes import generic +from django.contrib import contenttypes from django.core.urlresolvers import reverse from django.shortcuts import redirect from django.utils.functional import cached_property @@ -180,7 +180,7 @@ admin.site.register(MonitorData, MonitorDataAdmin) # Mokey-patching def resource_inline_factory(resources): - class ResourceInlineFormSet(generic.BaseGenericInlineFormSet): + class ResourceInlineFormSet(contenttype.forms.BaseGenericInlineFormSet): def total_form_count(self, resources=resources): return len(resources) @@ -220,7 +220,7 @@ def resource_inline_factory(resources): forms.append(self._construct_form(i, resource=resource)) return forms - class ResourceInline(generic.GenericTabularInline): + class ResourceInline(contenttype.admin.GenericTabularInline): model = ResourceData verbose_name_plural = _("resources") form = ResourceForm diff --git a/orchestra/contrib/resources/models.py b/orchestra/contrib/resources/models.py index 022910f0..2454b5de 100644 --- a/orchestra/contrib/resources/models.py +++ b/orchestra/contrib/resources/models.py @@ -2,7 +2,6 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelatio from django.contrib.contenttypes.models import ContentType from django.apps import apps from django.db import models -from django.db.models.loading import get_model from django.utils import timezone from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ @@ -106,7 +105,7 @@ class Resource(models.Model): try: self.get_model_path(monitor) except (RuntimeError, LookupError): - model = get_model(ServiceMonitor.get_backend(monitor).model) + model = apps.get_model(ServiceMonitor.get_backend(monitor).model) monitor_errors.append(model._meta.model_name) if monitor_errors: model_name = self.content_type.model_class()._meta.model_name diff --git a/orchestra/contrib/services/models.py b/orchestra/contrib/services/models.py index 9b832a01..3ebce599 100644 --- a/orchestra/contrib/services/models.py +++ b/orchestra/contrib/services/models.py @@ -2,7 +2,7 @@ import decimal from django.contrib.contenttypes.models import ContentType from django.db import models -from django.db.models.loading import get_model +from django.apps import apps from django.utils.functional import cached_property from django.utils.module_loading import autodiscover_modules from django.utils.translation import string_concat, ugettext_lazy as _ @@ -236,7 +236,7 @@ class Service(models.Model): return rate_class.get_methods()[self.rate_algorithm] def update_orders(self, commit=True): - order_model = get_model(settings.SERVICES_ORDER_MODEL) + order_model = apps.get_model(settings.SERVICES_ORDER_MODEL) related_model = self.content_type.model_class() updates = [] queryset = related_model.objects.all() diff --git a/orchestra/core/validators.py b/orchestra/core/validators.py index 750933ca..90fb0950 100644 --- a/orchestra/core/validators.py +++ b/orchestra/core/validators.py @@ -1,6 +1,9 @@ import re -import crack +try: + import crack +except: + import cracklib as crack import phonenumbers from django.core import validators diff --git a/orchestra/models/utils.py b/orchestra/models/utils.py index f4375e84..58a288d1 100644 --- a/orchestra/models/utils.py +++ b/orchestra/models/utils.py @@ -1,6 +1,6 @@ from django.conf import settings from django.db.models import loading -from django.utils import importlib +import importlib def get_model(label, import_module=True): diff --git a/orchestra/permissions/auth.py b/orchestra/permissions/auth.py index 2006ef6e..075dce6d 100644 --- a/orchestra/permissions/auth.py +++ b/orchestra/permissions/auth.py @@ -1,6 +1,5 @@ from django.contrib.auth.backends import ModelBackend -from django.db.models.loading import get_model, get_app, get_models - +from django.apps import apps class OrchestraPermissionBackend(ModelBackend): supports_object_permissions = True @@ -16,7 +15,7 @@ class OrchestraPermissionBackend(ModelBackend): if obj is None: app_label = perm.split('.')[0] model_label = perm.split('_')[1] - model = get_model(app_label, model_label) + model = apps.get_model(app_label, model_label) perm_manager = model else: perm_manager = obj @@ -34,8 +33,8 @@ class OrchestraPermissionBackend(ModelBackend): """ if not user.is_active: return False - app = get_app(app_label) - for model in get_models(app): + app = apps.get_app_config(app_label) + for model in apps.get_models(app): try: has_perm = model.has_permission.view(user) except AttributeError: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..a9f5a189 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,31 @@ +cracklib +psycopg2 +django==1.8 +django-celery-email==1.0.4 +https://github.com/glic3rinu/django-fluent-dashboard/archive/master.zip +https://bitbucket.org/izi/django-admin-tools/get/a0abfffd76a0.zip +IPy==0.81 +django-extensions==1.5.2 +django-transaction-signals==1.0.0 +django-celery==3.1.16 +celery==3.1.16 +kombu==3.0.23 +billiard==3.3.0.18 +Markdown==2.4 +djangorestframework==3.1.1 +paramiko==1.15.1 +ecdsa==0.11 +Pygments==1.6 +django-filter==0.7 +passlib==1.6.2 +jsonfield==0.9.22 +lxml==3.3.5 +python-dateutil==2.2 +django-iban==0.3.0 +requests +phonenumbers +django-countries +django-localflavor +###development +django-debug-toolbar +django-nose