zhurong d76bbb9949 Revert ThemableSelectWidget for themable selects
Now horizon ThemableSelectWidget field can not display
the validation error, just make the field keep the old
can temporary fix this. Once horizon fixed,
we can revert it back.

This reverts commit 85fc5e002c875be1a4f303fd37eb6456484be521.
Closes-Bug: #1711763

Change-Id: I557d38f739786597a9472c8104e1edf531e9a007
2017-08-25 10:30:42 +08:00

299 lines
12 KiB
Python

# Copyright (c) 2013 Mirantis, 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 json
import sys
from django.core.urlresolvers import reverse
from django.core import validators
from django import forms
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms as horizon_forms
from horizon import messages
from openstack_dashboard import policy
from oslo_log import log as logging
from muranoclient.common import exceptions as exc
from muranodashboard import api
from muranodashboard.packages import consts
LOG = logging.getLogger(__name__)
IMPORT_TYPE_CHOICES = [
('upload', _('File')),
('by_name', _('Repository')),
('by_url', _('URL')),
]
IMPORT_BUNDLE_TYPE_CHOICES = [
('by_name', _('Repository')),
('by_url', _('URL')),
]
class PackageURLField(forms.URLField):
default_validators = [validators.URLValidator(schemes=["http", "https"])]
class ImportBundleForm(forms.Form):
import_type = forms.ChoiceField(
label=_("Package Bundle Source"),
choices=IMPORT_BUNDLE_TYPE_CHOICES,
widget=forms.Select(attrs={
'class': 'switchable',
'data-slug': 'source'}))
url = PackageURLField(
label=_("Bundle URL"),
required=False,
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-by_url': _('Bundle URL')}),
help_text=_('An external http/https URL to load the bundle from.'))
name = forms.CharField(
label=_("Bundle Name"),
required=False,
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-by_name': _('Bundle Name')}),
help_text=_("Name of the bundle."))
def clean(self):
cleaned_data = super(ImportBundleForm, self).clean()
import_type = cleaned_data.get('import_type')
if import_type == 'by_name' and not cleaned_data.get('name'):
msg = _('Please supply a bundle name')
raise forms.ValidationError(msg)
elif import_type == 'by_url' and not cleaned_data.get('url'):
msg = _('Please supply a bundle url')
raise forms.ValidationError(msg)
return cleaned_data
class ImportPackageForm(forms.Form):
import_type = forms.ChoiceField(
label=_("Package Source"),
choices=IMPORT_TYPE_CHOICES,
widget=forms.Select(attrs={
'class': 'switchable',
'data-slug': 'source'}))
url = PackageURLField(
label=_("Package URL"),
required=False,
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-by_url': _('Package URL')}),
help_text=_('An external http/https URL to load the package from.'))
repo_name = horizon_forms.CharField(
label=_("Package Name"),
required=False,
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-by_name': _('Package Name')}),
help_text=_(
'Package name in the repository, usually a fully qualified name'),
)
package = forms.FileField(
label=_('Application Package'),
required=False,
widget=forms.FileInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-upload': _('Application Package')}),
help_text=_('A local zip file to upload'))
repo_version = horizon_forms.CharField(
label=_("Package version"),
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-by_name': _('Package version')}),
required=False)
def __init__(self, *args, **kwargs):
super(ImportPackageForm, self).__init__(*args, **kwargs)
self.fields['repo_version'].widget.attrs['placeholder'] = \
_('Optional')
def clean_package(self):
package = self.cleaned_data.get('package')
if package:
max_size_in_bytes = consts.MAX_FILE_SIZE_MB << 20
if package.size > max_size_in_bytes:
msg = _('It is forbidden to upload files larger than '
'{0} MB.').format(consts.MAX_FILE_SIZE_MB)
LOG.error(msg)
raise forms.ValidationError(msg)
return package
def clean(self):
cleaned_data = super(ImportPackageForm, self).clean()
import_type = cleaned_data.get('import_type')
if import_type == 'upload' and not cleaned_data.get('package'):
msg = _('Please supply a package file')
LOG.error(msg)
raise forms.ValidationError(msg)
elif import_type == 'by_name' and not cleaned_data.get('repo_name'):
msg = _('Please supply a package name')
LOG.error(msg)
raise forms.ValidationError(msg)
elif import_type == 'by_url' and not cleaned_data.get('url'):
msg = _('Please supply a package url')
LOG.error(msg)
raise forms.ValidationError(msg)
return cleaned_data
class PackageParamsMixin(forms.Form):
name = forms.CharField(label=_('Name'),
max_length=80,
help_text=_('80 characters max.'))
tags = forms.CharField(label=_('Tags'),
required=False,
help_text=_('Provide comma-separated list of words,'
' associated with the package'))
is_public = forms.BooleanField(label=_('Public'),
required=False,
widget=forms.CheckboxInput)
enabled = forms.BooleanField(label=_('Active'),
required=False,
widget=forms.CheckboxInput)
description = forms.CharField(label=_('Description'),
widget=forms.Textarea,
required=False)
def set_initial(self, request, package):
self.fields['name'].initial = package.name
self.fields['tags'].initial = ', '.join(package.tags)
self.fields['is_public'].initial = package.is_public
self.fields['enabled'].initial = package.enabled
self.fields['description'].initial = package.description
if not policy.check((("murano", "publicize_package"),), request):
self.fields['is_public'].widget = forms.CheckboxInput(
attrs={'readonly': 'readonly', 'disabled': 'disabled'})
self.fields['is_public'].help_text = _(
'You are not allowed to make packages public.')
class UpdatePackageForm(PackageParamsMixin):
def __init__(self, *args, **kwargs):
package = kwargs.pop('package')
request = kwargs.pop('request')
super(UpdatePackageForm, self).__init__(*args, **kwargs)
self.set_initial(request, package)
class ModifyPackageForm(PackageParamsMixin, horizon_forms.SelfHandlingForm):
def __init__(self, request, *args, **kwargs):
super(ModifyPackageForm, self).__init__(request, *args, **kwargs)
package = kwargs['initial']['package']
self.set_initial(request, package)
if package.type == 'Application':
self.fields['categories'] = forms.MultipleChoiceField(
label=_('Application Category'),
choices=[('', 'No categories available')],
required=False)
try:
categories = api.muranoclient(request).categories.list()
if categories:
category_names = [(c.name, c.name) for c in categories]
self.fields['categories'].choices = category_names
if package.categories:
self.fields['categories'].initial = dict(
(key, True) for key in package.categories)
except (exc.HTTPException, Exception):
msg = _('Unable to get list of categories')
LOG.exception(msg)
redirect = reverse('horizon:app-catalog:packages:index')
exceptions.handle(request,
msg,
redirect=redirect)
def handle(self, request, data):
app_id = self.initial.get('app_id')
LOG.debug('Updating package {0} with {1}'.format(app_id, data))
try:
data['tags'] = [t.strip() for t in data['tags'].split(',')]
result = api.muranoclient(request).packages.update(app_id, data)
messages.success(request, _('Package modified.'))
return result
except exc.HTTPForbidden:
msg = _("You are not allowed to perform this operation")
LOG.exception(msg)
exceptions.handle(
request,
msg,
redirect=reverse('horizon:app-catalog:packages:index'))
except exc.HTTPConflict:
msg = _('Package or Class with the same name is already made '
'public')
LOG.exception(msg)
messages.error(request, msg)
exceptions.handle(
request,
msg,
redirect=reverse('horizon:app-catalog:packages:index'))
except Exception as original_e:
reason = ''
exc_info = sys.exc_info()
if hasattr(original_e, 'details'):
try:
error = json.loads(original_e.details).get('error')
if error:
reason = error.get('message')
except ValueError:
# Let horizon operate with original exception
raise (exc_info[0], exc_info[1], exc_info[2])
msg = _('Failed to modify the package. {0}').format(reason)
LOG.exception(msg)
redirect = reverse('horizon:app-catalog:packages:index')
exceptions.handle(request,
msg,
redirect=redirect)
class SelectCategories(forms.Form):
categories = forms.MultipleChoiceField(
label=_('Application Category'),
choices=[('', _('No categories available'))],
required=False)
def __init__(self, *args, **kwargs):
request = kwargs.pop('request')
super(SelectCategories, self).__init__(*args, **kwargs)
try:
categories = api.muranoclient(request).categories.list()
if categories:
category_names = [(c.name, c.name) for c in categories]
self.fields['categories'].choices = category_names
except (exc.HTTPException, Exception):
msg = _('Unable to get list of categories')
LOG.exception(msg)
redirect = reverse('horizon:app-catalog:packages:index')
exceptions.handle(request,
msg,
redirect=redirect)