Commit 3d40e5f4 by Bach Dániel

Merge branch 'feature-django-1.7'

Conflicts:
	circle/dashboard/forms.py
parents 892f1470 f8759446
# -*- 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 'Level'
db.create_table(u'acl_level', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('codename', self.gf('django.db.models.fields.CharField')(max_length=100)),
('weight', self.gf('django.db.models.fields.IntegerField')(null=True)),
))
db.send_create_signal(u'acl', ['Level'])
# Adding unique constraint on 'Level', fields ['content_type', 'codename']
db.create_unique(u'acl_level', ['content_type_id', 'codename'])
# Adding model 'ObjectLevel'
db.create_table(u'acl_objectlevel', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['acl.Level'])),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('object_id', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal(u'acl', ['ObjectLevel'])
# Adding unique constraint on 'ObjectLevel', fields ['content_type', 'object_id', 'level']
db.create_unique(u'acl_objectlevel', ['content_type_id', 'object_id', 'level_id'])
# Adding M2M table for field users on 'ObjectLevel'
m2m_table_name = db.shorten_name(u'acl_objectlevel_users')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('objectlevel', models.ForeignKey(orm[u'acl.objectlevel'], null=False)),
('user', models.ForeignKey(orm[u'auth.user'], null=False))
))
db.create_unique(m2m_table_name, ['objectlevel_id', 'user_id'])
# Adding M2M table for field groups on 'ObjectLevel'
m2m_table_name = db.shorten_name(u'acl_objectlevel_groups')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('objectlevel', models.ForeignKey(orm[u'acl.objectlevel'], null=False)),
('group', models.ForeignKey(orm[u'auth.group'], null=False))
))
db.create_unique(m2m_table_name, ['objectlevel_id', 'group_id'])
def backwards(self, orm):
# Removing unique constraint on 'ObjectLevel', fields ['content_type', 'object_id', 'level']
db.delete_unique(u'acl_objectlevel', ['content_type_id', 'object_id', 'level_id'])
# Removing unique constraint on 'Level', fields ['content_type', 'codename']
db.delete_unique(u'acl_level', ['content_type_id', 'codename'])
# Deleting model 'Level'
db.delete_table(u'acl_level')
# Deleting model 'ObjectLevel'
db.delete_table(u'acl_objectlevel')
# Removing M2M table for field users on 'ObjectLevel'
db.delete_table(db.shorten_name(u'acl_objectlevel_users'))
# Removing M2M table for field groups on 'ObjectLevel'
db.delete_table(db.shorten_name(u'acl_objectlevel_groups'))
models = {
u'acl.level': {
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Level'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'weight': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
},
u'acl.objectlevel': {
'Meta': {'unique_together': "(('content_type', 'object_id', 'level'),)", 'object_name': 'ObjectLevel'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['acl.Level']"}),
'object_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['acl']
\ No newline at end of file
...@@ -15,29 +15,4 @@ ...@@ -15,29 +15,4 @@
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>. # with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.db.models import TextField, ForeignKey from .test_acl import TestModel, Test2Model # noqa
from django.contrib.auth.models import User
from ..models import AclBase
class TestModel(AclBase):
normal_field = TextField()
ACL_LEVELS = (
('alfa', 'Alfa'),
('bravo', 'Bravo'),
('charlie', 'Charlie'),
)
class Test2Model(AclBase):
normal2_field = TextField()
owner = ForeignKey(User, null=True)
ACL_LEVELS = (
('one', 'One'),
('two', 'Two'),
('three', 'Three'),
('owner', 'owner'),
)
...@@ -17,9 +17,31 @@ ...@@ -17,9 +17,31 @@
from django.test import TestCase from django.test import TestCase
from django.contrib.auth.models import User, Group, AnonymousUser from django.contrib.auth.models import User, Group, AnonymousUser
from django.db.models import TextField, ForeignKey
from ..models import ObjectLevel from ..models import ObjectLevel, AclBase
from .models import TestModel, Test2Model
class TestModel(AclBase):
normal_field = TextField()
ACL_LEVELS = (
('alfa', 'Alfa'),
('bravo', 'Bravo'),
('charlie', 'Charlie'),
)
class Test2Model(AclBase):
normal2_field = TextField()
owner = ForeignKey(User, null=True)
ACL_LEVELS = (
('one', 'One'),
('two', 'Two'),
('three', 'Three'),
('owner', 'owner'),
)
class AclUserTest(TestCase): class AclUserTest(TestCase):
......
...@@ -50,20 +50,20 @@ def get_env_variable(var_name, default=None): ...@@ -50,20 +50,20 @@ def get_env_variable(var_name, default=None):
########## PATH CONFIGURATION ########## PATH CONFIGURATION
# Absolute filesystem path to the Django project directory: # Absolute filesystem path to the Django project directory:
DJANGO_ROOT = dirname(dirname(abspath(__file__))) BASE_DIR = dirname(dirname(abspath(__file__)))
# Absolute filesystem path to the top-level project folder: # Absolute filesystem path to the top-level project folder:
SITE_ROOT = dirname(DJANGO_ROOT) SITE_ROOT = dirname(BASE_DIR)
# Site name: # Site name:
SITE_NAME = basename(DJANGO_ROOT) SITE_NAME = basename(BASE_DIR)
# Url to site: (e.g. http://localhost:8080/) # Url to site: (e.g. http://localhost:8080/)
DJANGO_URL = get_env_variable('DJANGO_URL', '/') DJANGO_URL = get_env_variable('DJANGO_URL', '/')
# Add our project to our pythonpath, this way we don't need to type our project # Add our project to our pythonpath, this way we don't need to type our project
# name in our dotted import paths: # name in our dotted import paths:
path.append(DJANGO_ROOT) path.append(BASE_DIR)
########## END PATH CONFIGURATION ########## END PATH CONFIGURATION
...@@ -78,14 +78,9 @@ TEMPLATE_DEBUG = DEBUG ...@@ -78,14 +78,9 @@ TEMPLATE_DEBUG = DEBUG
########## MANAGER CONFIGURATION ########## MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins # See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
('Root', 'root@localhost'),
)
EMAIL_SUBJECT_PREFIX = get_env_variable('DJANGO_SUBJECT_PREFIX', '[CIRCLE] ') EMAIL_SUBJECT_PREFIX = get_env_variable('DJANGO_SUBJECT_PREFIX', '[CIRCLE] ')
# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
MANAGERS = ADMINS
########## END MANAGER CONFIGURATION ########## END MANAGER CONFIGURATION
...@@ -283,12 +278,6 @@ TEMPLATE_CONTEXT_PROCESSORS = ( ...@@ -283,12 +278,6 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'dashboard.context_processors.extract_settings', 'dashboard.context_processors.extract_settings',
) )
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
TEMPLATE_DIRS = ( TEMPLATE_DIRS = (
normpath(join(SITE_ROOT, '../../site-circle/templates')), normpath(join(SITE_ROOT, '../../site-circle/templates')),
...@@ -337,7 +326,6 @@ DJANGO_APPS = ( ...@@ -337,7 +326,6 @@ DJANGO_APPS = (
) )
THIRD_PARTY_APPS = ( THIRD_PARTY_APPS = (
'south',
'django_tables2', 'django_tables2',
'crispy_forms', 'crispy_forms',
'djcelery', 'djcelery',
...@@ -349,6 +337,11 @@ THIRD_PARTY_APPS = ( ...@@ -349,6 +337,11 @@ THIRD_PARTY_APPS = (
'pipeline', 'pipeline',
) )
import django
if django.get_version() < '1.7':
THIRD_PARTY_APPS += 'south',
# Apps specific for this project go here. # Apps specific for this project go here.
LOCAL_APPS = ( LOCAL_APPS = (
'common', 'common',
...@@ -533,8 +526,14 @@ LOCALE_PATHS = (join(SITE_ROOT, 'locale'), ) ...@@ -533,8 +526,14 @@ LOCALE_PATHS = (join(SITE_ROOT, 'locale'), )
COMPANY_NAME = "BME IK 2014" COMPANY_NAME = "BME IK 2014"
SOUTH_MIGRATION_MODULES = { SOUTH_MIGRATION_MODULES = {
'taggit': 'taggit.south_migrations', 'taggit': 'taggit.south_migrations',
'vm': 'vm.south_migrations',
'firewall': 'firewall.south_migrations',
'acl': 'acl.south_migrations',
'dashboard': 'dashboard.south_migrations',
'storage': 'storage.south_migrations',
} }
graphite_host = environ.get("GRAPHITE_HOST", None) graphite_host = environ.get("GRAPHITE_HOST", None)
graphite_port = environ.get("GRAPHITE_PORT", None) graphite_port = environ.get("GRAPHITE_PORT", None)
if graphite_host and graphite_port: if graphite_host and graphite_port:
......
...@@ -43,7 +43,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' ...@@ -43,7 +43,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# DATABASES = { # DATABASES = {
# 'default': { # 'default': {
# 'ENGINE': 'django.db.backends.sqlite3', # 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': normpath(join(DJANGO_ROOT, 'default.db')), # 'NAME': normpath(join(BASE_DIR, 'default.db')),
# 'USER': '', # 'USER': '',
# 'PASSWORD': '', # 'PASSWORD': '',
# 'HOST': '', # 'HOST': '',
......
...@@ -370,6 +370,12 @@ class HumanSortField(CharField): ...@@ -370,6 +370,12 @@ class HumanSortField(CharField):
def get_monitored_value(self, instance): def get_monitored_value(self, instance):
return getattr(instance, self.monitor) return getattr(instance, self.monitor)
def deconstruct(self):
name, path, args, kwargs = super(HumanSortField, self).deconstruct()
if self.monitor is not None:
kwargs['monitor'] = self.monitor
return name, path, args, kwargs
@staticmethod @staticmethod
def _partition(s, pred): def _partition(s, pred):
"""Partition a deque of chars to a tuple of a """Partition a deque of chars to a tuple of a
......
...@@ -96,10 +96,10 @@ class VmSaveForm(OperationForm): ...@@ -96,10 +96,10 @@ class VmSaveForm(OperationForm):
if default: if default:
self.fields['name'].initial = default self.fields['name'].initial = default
if clone: if clone:
self.fields.insert(2, "clone", forms.BooleanField( self.fields["clone"] = forms.BooleanField(
required=False, label=_("Clone template permissions"), required=False, label=_("Clone template permissions"),
help_text=_("Clone the access list of parent template. Useful " help_text=_("Clone the access list of parent template. Useful "
"for updating a template."))) "for updating a template."))
class VmCustomizeForm(forms.Form): class VmCustomizeForm(forms.Form):
...@@ -750,9 +750,9 @@ class VmRenewForm(OperationForm): ...@@ -750,9 +750,9 @@ class VmRenewForm(OperationForm):
default = kwargs.pop('default') default = kwargs.pop('default')
super(VmRenewForm, self).__init__(*args, **kwargs) super(VmRenewForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'lease', forms.ModelChoiceField( self.fields['lease'] = forms.ModelChoiceField(
queryset=choices, initial=default, required=False, queryset=choices, initial=default, required=False,
empty_label=None, label=_('Length'))) empty_label=None, label=_('Length'))
if len(choices) < 2: if len(choices) < 2:
self.fields['lease'].widget = HiddenInput() self.fields['lease'].widget = HiddenInput()
self.fields['save'].widget = HiddenInput() self.fields['save'].widget = HiddenInput()
...@@ -772,9 +772,9 @@ class VmMigrateForm(forms.Form): ...@@ -772,9 +772,9 @@ class VmMigrateForm(forms.Form):
default = kwargs.pop('default') default = kwargs.pop('default')
super(VmMigrateForm, self).__init__(*args, **kwargs) super(VmMigrateForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'to_node', forms.ModelChoiceField( self.fields['to_node'] = forms.ModelChoiceField(
queryset=choices, initial=default, required=False, queryset=choices, initial=default, required=False,
widget=forms.RadioSelect(), label=_("Node"))) widget=forms.RadioSelect(), label=_("Node"))
class VmStateChangeForm(OperationForm): class VmStateChangeForm(OperationForm):
...@@ -835,9 +835,9 @@ class VmDiskResizeForm(OperationForm): ...@@ -835,9 +835,9 @@ class VmDiskResizeForm(OperationForm):
super(VmDiskResizeForm, self).__init__(*args, **kwargs) super(VmDiskResizeForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'disk', forms.ModelChoiceField( self.fields['disk'] = forms.ModelChoiceField(
queryset=choices, initial=self.disk, required=True, queryset=choices, initial=self.disk, required=True,
empty_label=None, label=_('Disk'))) empty_label=None, label=_('Disk'))
if self.disk: if self.disk:
self.fields['disk'].widget = HiddenInput() self.fields['disk'].widget = HiddenInput()
self.fields['size'].initial += self.disk.size self.fields['size'].initial += self.disk.size
...@@ -871,9 +871,9 @@ class VmDiskRemoveForm(OperationForm): ...@@ -871,9 +871,9 @@ class VmDiskRemoveForm(OperationForm):
super(VmDiskRemoveForm, self).__init__(*args, **kwargs) super(VmDiskRemoveForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'disk', forms.ModelChoiceField( self.fields['disk'] = forms.ModelChoiceField(
queryset=choices, initial=self.disk, required=True, queryset=choices, initial=self.disk, required=True,
empty_label=None, label=_('Disk'))) empty_label=None, label=_('Disk'))
if self.disk: if self.disk:
self.fields['disk'].widget = HiddenInput() self.fields['disk'].widget = HiddenInput()
...@@ -916,9 +916,9 @@ class VmRemoveInterfaceForm(OperationForm): ...@@ -916,9 +916,9 @@ class VmRemoveInterfaceForm(OperationForm):
super(VmRemoveInterfaceForm, self).__init__(*args, **kwargs) super(VmRemoveInterfaceForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'interface', forms.ModelChoiceField( self.fields['interface'] = forms.ModelChoiceField(
queryset=choices, initial=self.interface, required=True, queryset=choices, initial=self.interface, required=True,
empty_label=None, label=_('Interface'))) empty_label=None, label=_('Interface'))
if self.interface: if self.interface:
self.fields['interface'].widget = HiddenInput() self.fields['interface'].widget = HiddenInput()
...@@ -983,14 +983,14 @@ class VmDeployForm(OperationForm): ...@@ -983,14 +983,14 @@ class VmDeployForm(OperationForm):
super(VmDeployForm, self).__init__(*args, **kwargs) super(VmDeployForm, self).__init__(*args, **kwargs)
if choices is not None: if choices is not None:
self.fields.insert(0, 'node', DeployChoiceField( self.fields['node'] = DeployChoiceField(
queryset=choices, required=False, label=_('Node'), help_text=_( queryset=choices, required=False, label=_('Node'), help_text=_(
"Deploy virtual machine to this node " "Deploy virtual machine to this node "
"(blank allows scheduling automatically)."), "(blank allows scheduling automatically)."),
widget=forms.Select(attrs={ widget=forms.Select(attrs={
'class': "font-awesome-font", 'class': "font-awesome-font",
}), instance=instance }), instance=instance
)) )
class VmPortRemoveForm(OperationForm): class VmPortRemoveForm(OperationForm):
...@@ -1000,9 +1000,9 @@ class VmPortRemoveForm(OperationForm): ...@@ -1000,9 +1000,9 @@ class VmPortRemoveForm(OperationForm):
super(VmPortRemoveForm, self).__init__(*args, **kwargs) super(VmPortRemoveForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'rule', forms.ModelChoiceField( self.fields['rule'] = forms.ModelChoiceField(
queryset=choices, initial=self.rule, required=True, queryset=choices, initial=self.rule, required=True,
empty_label=None, label=_('Port'))) empty_label=None, label=_('Port'))
if self.rule: if self.rule:
self.fields['rule'].widget = HiddenInput() self.fields['rule'].widget = HiddenInput()
...@@ -1019,9 +1019,9 @@ class VmPortAddForm(OperationForm): ...@@ -1019,9 +1019,9 @@ class VmPortAddForm(OperationForm):
super(VmPortAddForm, self).__init__(*args, **kwargs) super(VmPortAddForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'host', forms.ModelChoiceField( self.fields['host'] = forms.ModelChoiceField(
queryset=choices, initial=self.host, required=True, queryset=choices, initial=self.host, required=True,
empty_label=None, label=_('Host'))) empty_label=None, label=_('Host'))
if self.host: if self.host:
self.fields['host'].widget = HiddenInput() self.fields['host'].widget = HiddenInput()
......
...@@ -54,7 +54,9 @@ from .validators import connect_command_template_validator ...@@ -54,7 +54,9 @@ from .validators import connect_command_template_validator
logger = getLogger(__name__) logger = getLogger(__name__)
pwgen = User.objects.make_random_password
def pwgen():
return User.objects.make_random_password()
class Favourite(Model): class Favourite(Model):
......
...@@ -20,7 +20,7 @@ Do you want to perform the following operation on ...@@ -20,7 +20,7 @@ Do you want to perform the following operation on
<a class="btn btn-default" href="{{object.get_absolute_url}}" <a class="btn btn-default" href="{{object.get_absolute_url}}"
data-dismiss="modal">{% trans "Cancel" %}</a> data-dismiss="modal">{% trans "Cancel" %}</a>
<button class="btn btn-{{ opview.effect }} btn-op-form-send" type="submit" id="op-form-send"> <button class="btn btn-{{ opview.effect }} btn-op-form-send" type="submit" id="op-form-send">
{% if opview.icon %}<i class="fa fa-fw fa-{{opview.icon}}"></i> {% endif %}{{ op|capfirst }} {% if opview.icon %}<i class="fa fa-fw fa-{{opview.icon}}"></i> {% endif %}{{ op.name|capfirst }}
</button> </button>
</div> </div>
</form> </form>
...@@ -389,6 +389,7 @@ class RenewViewTest(unittest.TestCase): ...@@ -389,6 +389,7 @@ class RenewViewTest(unittest.TestCase):
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.name = 'foo' inst.name = 'foo'
inst.lease = MagicMock(pk=99)
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = inst go.return_value = inst
...@@ -403,6 +404,7 @@ class RenewViewTest(unittest.TestCase): ...@@ -403,6 +404,7 @@ class RenewViewTest(unittest.TestCase):
patch('dashboard.views.util.messages') as msg: patch('dashboard.views.util.messages') as msg:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.lease = MagicMock(pk=99)
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
...@@ -421,6 +423,7 @@ class RenewViewTest(unittest.TestCase): ...@@ -421,6 +423,7 @@ class RenewViewTest(unittest.TestCase):
patch('dashboard.views.util.messages') as msg: patch('dashboard.views.util.messages') as msg:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.lease = MagicMock(pk=99)
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
...@@ -463,6 +466,7 @@ class RenewViewTest(unittest.TestCase): ...@@ -463,6 +466,7 @@ class RenewViewTest(unittest.TestCase):
with patch.object(view, 'get_object') as go: with patch.object(view, 'get_object') as go:
inst = MagicMock(spec=Instance, pk=11) inst = MagicMock(spec=Instance, pk=11)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.lease = MagicMock(pk=99)
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = False inst.has_level.return_value = False
......
...@@ -62,7 +62,7 @@ class GraphViewBase(LoginRequiredMixin, View): ...@@ -62,7 +62,7 @@ class GraphViewBase(LoginRequiredMixin, View):
metric = self.create_class(metric)(instance) metric = self.create_class(metric)(instance)
return HttpResponse(metric.get_graph(graphite_url, time), return HttpResponse(metric.get_graph(graphite_url, time),
mimetype="image/png") content_type="image/png")
def get_object(self, request, pk): def get_object(self, request, pk):
instance = self.model.objects.get(id=pk) instance = self.model.objects.get(id=pk)
......
...@@ -267,6 +267,9 @@ class UserCreationView(LoginRequiredMixin, PermissionRequiredMixin, ...@@ -267,6 +267,9 @@ class UserCreationView(LoginRequiredMixin, PermissionRequiredMixin,
template_name = 'dashboard/user-create.html' template_name = 'dashboard/user-create.html'
permission_required = "auth.add_user" permission_required = "auth.add_user"
def get_success_url(self):
reverse('dashboard.views.group-detail', args=[self.group.pk])
def get_group(self, group_pk): def get_group(self, group_pk):
self.group = get_object_or_404(Group, pk=group_pk) self.group = get_object_or_404(Group, pk=group_pk)
if not self.group.profile.has_level(self.request.user, 'owner'): if not self.group.profile.has_level(self.request.user, 'owner'):
......
...@@ -1151,7 +1151,7 @@ def get_vm_screenshot(request, pk): ...@@ -1151,7 +1151,7 @@ def get_vm_screenshot(request, pk):
# TODO handle this better # TODO handle this better
raise Http404() raise Http404()
return HttpResponse(image, mimetype="image/png") return HttpResponse(image, content_type="image/png")
class InstanceActivityDetail(CheckedDetailView): class InstanceActivityDetail(CheckedDetailView):
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals