Allows the creation of related objects during a workflow.
For example, this patch implements importing keypairs during
the launch instance workflow and allocating floating IP
addresses during the floating IP associate workflow.
This required several significant changes:
* SelfHandlingForm should no long return a redirect.
Instead, it should return either the object it
created/acted on, or else a boolean such as True.
* The ModalFormView now differentiates between GET
and POST.
* Due to the previous two items, SelfHandlingForm
was mostly gutted (no more maybe_handle, etc.).
* Modals now operate via a "stack" where only the
top modal is visible at any given time and closing
one causes the next one to become visible.
In the process of these large changes there was a large
amount of general code cleanup, especially in the javascript
code and the existing SelfHandlingForm subclasses/ModalFormView
subclasses. Many small bugs were fixed along with the cleanup.
Implements blueprint inline-object-creation.
Fixes bug 994677.
Fixes bug 1025977.
Fixes bug 1027342.
Fixes bug 1025919.
Change-Id: I1808b34cbf6f813eaedf767a6364e815c0c5e969
140 lines
5.7 KiB
Python
140 lines
5.7 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2012 United States Government as represented by the
|
|
# Administrator of the National Aeronautics and Space Administration.
|
|
# All Rights Reserved.
|
|
#
|
|
# Copyright 2012 Nebula, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import logging
|
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from horizon import api
|
|
from horizon import exceptions
|
|
from horizon import forms
|
|
from horizon import messages
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class AddUser(forms.SelfHandlingForm):
|
|
tenant_id = forms.CharField(widget=forms.widgets.HiddenInput())
|
|
user_id = forms.CharField(widget=forms.widgets.HiddenInput())
|
|
role_id = forms.ChoiceField(label=_("Role"))
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
roles = kwargs.pop('roles')
|
|
super(AddUser, self).__init__(*args, **kwargs)
|
|
role_choices = [(role.id, role.name) for role in roles]
|
|
self.fields['role_id'].choices = role_choices
|
|
|
|
def handle(self, request, data):
|
|
try:
|
|
api.add_tenant_user_role(request,
|
|
data['tenant_id'],
|
|
data['user_id'],
|
|
data['role_id'])
|
|
messages.success(request, _('Successfully added user to project.'))
|
|
return True
|
|
except:
|
|
exceptions.handle(request, _('Unable to add user to project.'))
|
|
|
|
|
|
class CreateTenant(forms.SelfHandlingForm):
|
|
name = forms.CharField(label=_("Name"))
|
|
description = forms.CharField(
|
|
widget=forms.widgets.Textarea(),
|
|
label=_("Description"),
|
|
required=False)
|
|
enabled = forms.BooleanField(label=_("Enabled"), required=False,
|
|
initial=True)
|
|
|
|
def handle(self, request, data):
|
|
try:
|
|
LOG.info('Creating project with name "%s"' % data['name'])
|
|
project = api.tenant_create(request,
|
|
data['name'],
|
|
data['description'],
|
|
data['enabled'])
|
|
messages.success(request,
|
|
_('%s was successfully created.')
|
|
% data['name'])
|
|
return project
|
|
except:
|
|
exceptions.handle(request, _('Unable to create project.'))
|
|
|
|
|
|
class UpdateTenant(forms.SelfHandlingForm):
|
|
id = forms.CharField(label=_("ID"),
|
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
|
name = forms.CharField(label=_("Name"))
|
|
description = forms.CharField(
|
|
widget=forms.widgets.Textarea(),
|
|
label=_("Description"))
|
|
enabled = forms.BooleanField(required=False, label=_("Enabled"))
|
|
|
|
def handle(self, request, data):
|
|
try:
|
|
LOG.info('Updating project with id "%s"' % data['id'])
|
|
project = api.tenant_update(request,
|
|
data['id'],
|
|
data['name'],
|
|
data['description'],
|
|
data['enabled'])
|
|
messages.success(request,
|
|
_('%s was successfully updated.')
|
|
% data['name'])
|
|
return project
|
|
except:
|
|
exceptions.handle(request, _('Unable to update project.'))
|
|
|
|
|
|
class UpdateQuotas(forms.SelfHandlingForm):
|
|
tenant_id = forms.CharField(label=_("ID (name)"),
|
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
|
metadata_items = forms.IntegerField(label=_("Metadata Items"))
|
|
injected_files = forms.IntegerField(label=_("Injected Files"))
|
|
injected_file_content_bytes = forms.IntegerField(label=_("Injected File "
|
|
"Content Bytes"))
|
|
cores = forms.IntegerField(label=_("VCPUs"))
|
|
instances = forms.IntegerField(label=_("Instances"))
|
|
volumes = forms.IntegerField(label=_("Volumes"))
|
|
gigabytes = forms.IntegerField(label=_("Gigabytes"))
|
|
ram = forms.IntegerField(label=_("RAM (in MB)"))
|
|
floating_ips = forms.IntegerField(label=_("Floating IPs"))
|
|
|
|
def handle(self, request, data):
|
|
ifcb = data['injected_file_content_bytes']
|
|
try:
|
|
api.nova.tenant_quota_update(request,
|
|
data['tenant_id'],
|
|
metadata_items=data['metadata_items'],
|
|
injected_file_content_bytes=ifcb,
|
|
volumes=data['volumes'],
|
|
gigabytes=data['gigabytes'],
|
|
ram=data['ram'],
|
|
floating_ips=data['floating_ips'],
|
|
instances=data['instances'],
|
|
injected_files=data['injected_files'],
|
|
cores=data['cores'])
|
|
messages.success(request,
|
|
_('Quotas for %s were successfully updated.')
|
|
% data['tenant_id'])
|
|
return True
|
|
except:
|
|
exceptions.handle(request, _('Unable to update quotas.'))
|