Commit 48c95e94 by Szabolcs Gelencser

Implement proper role assignment to leases

parent bdcb0d24
......@@ -45,4 +45,6 @@ scripts.rc
# less
*.css
circle/celery
\ No newline at end of file
circle/celery
circle/circle/db.sqlite3
.idea
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$/circle" />
<option name="settingsModule" value="circle/settings/local.py" />
<option name="manageScript" value="manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 2.7 (cloud)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/circle/network/templates" />
</list>
</option>
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="dataSourceStorageLocal">
<data-source name="Django default" uuid="e21df92f-3677-4e60-b52d-95bf8bd42c58">
<database-info product="" version="" jdbc-version="" driver-name="" driver-version="" />
<auth-required>false</auth-required>
<first-sync>true</first-sync>
</data-source>
<data-source name="db.sqlite3" uuid="4255fd52-caf4-4a1f-903a-d9a435b0487e">
<database-info product="SQLite" version="3.16.1" jdbc-version="2.1" driver-name="SQLiteJDBC" driver-version="native" />
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<secret-storage>master_key</secret-storage>
<auth-required>false</auth-required>
<introspection-schemas>*:main</introspection-schemas>
</data-source>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Django default" uuid="e21df92f-3677-4e60-b52d-95bf8bd42c58">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<remarks>$PROJECT_DIR$/circle/circle/settings/base.py</remarks>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/circle/circle/db.sqlite3</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
</data-source>
<data-source source="LOCAL" name="db.sqlite3" uuid="4255fd52-caf4-4a1f-903a-d9a435b0487e">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/circle/circle/db.sqlite3</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
</data-source>
</component>
</project>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ourVersions">
<value>
<list size="2">
<item index="0" class="java.lang.String" itemvalue="2.7" />
<item index="1" class="java.lang.String" itemvalue="3.6" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="11">
<item index="0" class="java.lang.String" itemvalue="salt" />
<item index="1" class="java.lang.String" itemvalue="six" />
<item index="2" class="java.lang.String" itemvalue="netaddr" />
<item index="3" class="java.lang.String" itemvalue="requests" />
<item index="4" class="java.lang.String" itemvalue="cryptography" />
<item index="5" class="java.lang.String" itemvalue="psycopg2" />
<item index="6" class="java.lang.String" itemvalue="lxml" />
<item index="7" class="java.lang.String" itemvalue="MarkupSafe" />
<item index="8" class="java.lang.String" itemvalue="pylibmc" />
<item index="9" class="java.lang.String" itemvalue="pytz" />
<item index="10" class="java.lang.String" itemvalue="simplejson" />
</list>
</value>
</option>
</inspection_tool>
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7 (cloud)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="2" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cloud.iml" filepath="$PROJECT_DIR$/.idea/cloud.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -557,27 +557,30 @@ class TemplateForm(forms.ModelForm):
}
class LeaseRolesForm(forms.Form):
class LeaseForm(forms.ModelForm):
name = forms.CharField(max_length=100, label=_("Name"))
roles = forms.MultipleChoiceField(
required=False,
widget=forms.SelectMultiple(attrs={
'class': "form-control",
'style': "height: 234px",
})
)
def __init__(self, roles, *args, **kwargs):
lease = kwargs.pop("lease", None)
super(LeaseRolesForm, self).__init__(*args, **kwargs)
self.fields['roles'].choices = (
(role.id, role.name) for role in roles
)
def __init__(self, *args, **kwargs):
roles = kwargs.pop("roles", None)
super(LeaseForm, self).__init__(*args, **kwargs)
class LeaseForm(forms.ModelForm):
if roles:
self.fields['roles'].choices = (
(role.id, role.name) for role in roles
)
def __init__(self, *args, **kwargs):
super(LeaseForm, self).__init__(*args, **kwargs)
related_roles = self.instance.roles_permitted.all()
self.fields['roles'].initial = [
role.role_id for role in related_roles
]
self.generate_fields()
# e2ae8b048e7198428f696375b8bdcd89e90002d1/django/utils/timesince.py#L10
......@@ -619,7 +622,13 @@ class LeaseForm(forms.ModelForm):
for m in methods:
for idx, i in enumerate(intervals):
self.fields["%s_%s" % (m, i)] = forms.IntegerField(
min_value=0, widget=NumberInput,
min_value=0, widget=NumberInput(
attrs={
'class': "form-control numberinput form-control",
'min': '0',
'style': 'min-width: 80px'
}
),
initial=initial[m].get(i, 0))
def save(self, commit=True):
......@@ -639,70 +648,19 @@ class LeaseForm(forms.ModelForm):
)
self.instance.delete_interval = delete_seconds
self.instance.suspend_interval = suspend_seconds
self.instance.roles_permitted.clear()
for role_id in data['roles']:
try:
self.instance.roles_permitted.add(Role.objects.get(role_id=role_id))
except Role.DoesNotExist:
self.instance.roles_permitted.create(role_id=role_id)
instance = super(LeaseForm, self).save(commit=False)
if commit:
instance.save()
return instance
@property
def helper(self):
helper = FormHelper()
helper.layout = Layout(
Field('name'),
Field("suspend_interval_seconds", type="hidden", value="0"),
Field("delete_interval_seconds", type="hidden", value="0"),
HTML(string_concat("<label>", _("Suspend in"), "</label>")),
Div(
NumberField("suspend_hours", css_class="form-control"),
Div(
HTML(_("hours")),
css_class="input-group-addon",
),
NumberField("suspend_days", css_class="form-control"),
Div(
HTML(_("days")),
css_class="input-group-addon",
),
NumberField("suspend_weeks", css_class="form-control"),
Div(
HTML(_("weeks")),
css_class="input-group-addon",
),
NumberField("suspend_months", css_class="form-control"),
Div(
HTML(_("months")),
css_class="input-group-addon",
),
css_class="input-group interval-input",
),
HTML(string_concat("<label>", _("Delete in"), "</label>")),
Div(
NumberField("delete_hours", css_class="form-control"),
Div(
HTML(_("hours")),
css_class="input-group-addon",
),
NumberField("delete_days", css_class="form-control"),
Div(
HTML(_("days")),
css_class="input-group-addon",
),
NumberField("delete_weeks", css_class="form-control"),
Div(
HTML(_("weeks")),
css_class="input-group-addon",
),
NumberField("delete_months", css_class="form-control"),
Div(
HTML(_("months")),
css_class="input-group-addon",
),
css_class="input-group interval-input",
)
)
helper.add_input(Submit("submit", _("Save changes")))
return helper
class Meta:
model = Lease
exclude = ()
......
......@@ -5,38 +5,71 @@
{% block title-page %}{% trans "Edit lease" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-7">
<div class="panel panel-default">
<div class="panel-heading">
<a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.template-list" %}">{% trans "Back" %}</a>
<h3 class="no-margin"><i class="fa fa-clock-o"></i> {% trans "Edit lease" %}</h3>
</div>
<div class="panel-body">
{% with form=form %}
{% include "display-form-errors.html" %}
{% endwith %}
{% crispy form %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.template-list" %}">{% trans "Back" %}</a>
<h3 class="no-margin"><i class="fa fa-clock-o"></i> {% trans "Edit lease" %}</h3>
</div>
<div class="col-md-5">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="no-margin"><i class="icon-group"></i> {% trans "Manage access" %}</h4>
</div>
<div class="panel-body">
<form action="{% url "dashboard.views.lease-acl" pk=object.pk %}" method="post">
{% csrf_token %}
{{ lease_roles_form.roles }}
<div class="pull-right" style="margin-top: 20px">
<button type="submit" class="btn btn-success">{% trans "Save" %}</button>
<div class="panel-body">
{% with form=form %}
{% include "display-form-errors.html" %}
{% endwith %}
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-md-7">
{{ form.name|as_crispy_field }}
<label>Suspend in</label>
<div class="input-group interval-input">
{{ form.suspend_hours }}
<div class="input-group-addon">hours</div>
{{ form.suspend_days }}
<div class="input-group-addon">days</div>
{{ form.suspend_weeks }}
<div class="input-group-addon">weeks</div>
{{ form.suspend_months }}
<div class="input-group-addon">months</div>
</div>
<label>Delete in</label>
<div class="input-group interval-input">
{{ form.delete_hours }}
<div class="input-group-addon">hours</div>
{{ form.delete_days }}
<div class="input-group-addon">days</div>
{{ form.delete_weeks }}
<div class="input-group-addon">weeks</div>
{{ form.delete_months }}
<div class="input-group-addon">months</div>
</div>
</div>
<div class="col-md-5">
{{ form.roles }}
</div>
</form>
</div>
</div>
<div class="form-group container-fluid">
<div class="controls ">
<input type="submit" name="submit" value="Save changes" class="btn btn-primary" id="submit-id-submit">
</div>
</div>
</div>
</form>
</div>
</div>
{# <div class="col-md-5">#}
{# <div class="panel panel-default">#}
{# <div class="panel-heading">#}
{# <h4 class="no-margin"><i class="icon-group"></i> {% trans "Manage access" %}</h4>#}
{# </div>#}
{# <div class="panel-body">#}
{# <form action="{% url "dashboard.views.lease-acl" pk=object.pk %}" method="post">#}
{# {% csrf_token %}#}
{##}
{# <div class="pull-right" style="margin-top: 1em">#}
{# <button type="submit" class="btn btn-success">{% trans "Save" %}</button>#}
{# </div>#}
{# </form>#}
{# </div>#}
{# </div>#}
{# </div>#}
{% endblock %}
......@@ -19,8 +19,7 @@ from __future__ import absolute_import
from dashboard.views.autocomplete import AclUserGroupAutocomplete, AclUserAutocomplete
from dashboard.views.template import TemplateList, TemplateChoose, TemplateDetail, TemplateDelete, \
TransferTemplateOwnershipConfirmView, TransferTemplateOwnershipView, LeaseCreate, LeaseDetail, LeaseDelete, \
LeaseAclUpdateView
TransferTemplateOwnershipConfirmView, TransferTemplateOwnershipView, LeaseCreate, LeaseDetail, LeaseDelete
from dashboard.views.vm import VmDetailView, VmList, VmCreate, vm_activity, vm_ops, FavouriteView, VmPlainImageCreate
from django.conf.urls import url
......@@ -41,8 +40,8 @@ urlpatterns = [
name="dashboard.views.lease-create"),
url(r'^lease/delete/(?P<pk>\d+)/$', LeaseDelete.as_view(),
name="dashboard.views.lease-delete"),
url(r'^lease/(?P<pk>\d+)/acl/$', LeaseAclUpdateView.as_view(),
name="dashboard.views.lease-acl"),
# url(r'^lease/(?P<pk>\d+)/acl/$', LeaseAclUpdateView.as_view(),
# name="dashboard.views.lease-acl"),
#
# url(r'^template/create/$', TemplateCreate.as_view(),
# name="dashboard.views.template-create"),
......
......@@ -31,6 +31,7 @@ from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, get_object_or_404
from django.utils import timezone
from django.utils.translation import ugettext as _, ugettext_noop
from django.views import View
from django.views.generic import (
TemplateView, CreateView, UpdateView,
)
......@@ -38,6 +39,7 @@ from django.views.generic import (
from braces.views import (
LoginRequiredMixin, PermissionRequiredMixin,
)
from django.views.generic.edit import BaseUpdateView, ModelFormMixin, FormView
from django_tables2 import SingleTableView
from vm.models import (
......@@ -47,7 +49,7 @@ from storage.models import Disk
from ..forms import (
TemplateForm, TemplateListSearchForm, AclUserOrGroupAddForm, LeaseForm,
LeaseRolesForm)
)
from ..tables import TemplateListTable, LeaseListTable
from .util import (
......@@ -414,10 +416,6 @@ class LeaseCreate(LoginRequiredMixin, PolicyMixin,
return reverse_lazy("dashboard.views.template-list")
class LeaseAclUpdateView(AclUpdateView):
model = Lease
class LeaseDetail(LoginRequiredMixin, PolicyMixin,
SuccessMessageMixin, UpdateView):
model = Lease
......@@ -429,15 +427,11 @@ class LeaseDetail(LoginRequiredMixin, PolicyMixin,
def get_success_url(self):
return reverse_lazy("dashboard.views.lease-detail", kwargs=self.kwargs)
def get_context_data(self, **kwargs):
def get_form_kwargs(self):
from openstack_api import keystone
roles = keystone.role_list(self.request)
context = super(LeaseDetail, self).get_context_data(**kwargs)
context.update({
'lease_roles_form': LeaseRolesForm(roles),
})
return context
kwargs = super(LeaseDetail, self).get_form_kwargs()
kwargs['roles'] = keystone.role_list(self.request)
return kwargs
class LeaseDelete(DeleteViewBase):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-22 12:29
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('vm', '0014_auto_20180518_1125'),
]
operations = [
migrations.AlterModelTable(
name='role',
table='vm_lease_role',
),
]
......@@ -67,6 +67,10 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
class Role(Model):
role_id = CharField(blank=False, max_length=100, unique=True)
class Meta:
app_label = 'vm'
db_table = 'vm_lease_role'
class Lease(Model):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment