horizon/openstack_dashboard/dashboards/project/instances/forms.py
LIU Yulong d3dd5e0ff0 Make no response notification(msg) level to INFO
Some API calls just sent but the results were uncertain,
Horizon should notify the user that your request is
just accepted, not successfully.
So this patch change some form message level to INFO,
and some message expression.

Change-Id: I241cd9cf3ad6b2bd747e3ea1c6040a140ba77b56
Closes-Bug: #1326301
Closes-Bug: #1286418
2016-03-29 21:12:31 +08:00

236 lines
10 KiB
Python

# Copyright 2013 OpenStack Foundation
# All Rights Reserved.
#
# 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.
from django.core.urlresolvers import reverse
from django.template.defaultfilters import filesizeformat # noqa
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.debug import sensitive_variables # noqa
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon.utils import validators
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.images \
import utils as image_utils
from openstack_dashboard.dashboards.project.instances \
import utils as instance_utils
def _image_choice_title(img):
gb = filesizeformat(img.size)
return '%s (%s)' % (img.name or img.id, gb)
class RebuildInstanceForm(forms.SelfHandlingForm):
instance_id = forms.CharField(widget=forms.HiddenInput())
image = forms.ChoiceField(
label=_("Select Image"),
widget=forms.SelectWidget(attrs={'class': 'image-selector'},
data_attrs=('size', 'display-name'),
transform=_image_choice_title))
password = forms.RegexField(
label=_("Rebuild Password"),
required=False,
widget=forms.PasswordInput(render_value=False),
regex=validators.password_validator(),
error_messages={'invalid': validators.password_validator_msg()})
confirm_password = forms.CharField(
label=_("Confirm Rebuild Password"),
required=False,
widget=forms.PasswordInput(render_value=False))
disk_config = forms.ChoiceField(label=_("Disk Partition"),
required=False)
def __init__(self, request, *args, **kwargs):
super(RebuildInstanceForm, self).__init__(request, *args, **kwargs)
instance_id = kwargs.get('initial', {}).get('instance_id')
self.fields['instance_id'].initial = instance_id
images = image_utils.get_available_images(request,
request.user.tenant_id)
choices = [(image.id, image) for image in images]
if choices:
choices.insert(0, ("", _("Select Image")))
else:
choices.insert(0, ("", _("No images available")))
self.fields['image'].choices = choices
if not api.nova.can_set_server_password():
del self.fields['password']
del self.fields['confirm_password']
try:
if not api.nova.extension_supported("DiskConfig", request):
del self.fields['disk_config']
else:
# Set our disk_config choices
config_choices = [("AUTO", _("Automatic")),
("MANUAL", _("Manual"))]
self.fields['disk_config'].choices = config_choices
except Exception:
exceptions.handle(request, _('Unable to retrieve extensions '
'information.'))
def clean(self):
cleaned_data = super(RebuildInstanceForm, self).clean()
if 'password' in cleaned_data:
passwd = cleaned_data.get('password')
confirm = cleaned_data.get('confirm_password')
if passwd is not None and confirm is not None:
if passwd != confirm:
raise forms.ValidationError(_("Passwords do not match."))
return cleaned_data
# We have to protect the entire "data" dict because it contains the
# password and confirm_password strings.
@sensitive_variables('data', 'password')
def handle(self, request, data):
instance = data.get('instance_id')
image = data.get('image')
password = data.get('password') or None
disk_config = data.get('disk_config', None)
try:
api.nova.server_rebuild(request, instance, image, password,
disk_config)
messages.info(request, _('Rebuilding instance %s.') % instance)
except Exception:
redirect = reverse('horizon:project:instances:index')
exceptions.handle(request, _("Unable to rebuild instance."),
redirect=redirect)
return True
class DecryptPasswordInstanceForm(forms.SelfHandlingForm):
instance_id = forms.CharField(widget=forms.HiddenInput())
_keypair_name_label = _("Key Pair Name")
_keypair_name_help = _("The Key Pair name that "
"was associated with the instance")
_attrs = {'readonly': 'readonly', 'rows': 4}
keypair_name = forms.CharField(widget=forms.widgets.TextInput(_attrs),
label=_keypair_name_label,
help_text=_keypair_name_help,
required=False)
_encrypted_pwd_help = _("The instance password encrypted "
"with your public key.")
encrypted_password = forms.CharField(widget=forms.widgets.Textarea(_attrs),
label=_("Encrypted Password"),
help_text=_encrypted_pwd_help,
required=False)
def __init__(self, request, *args, **kwargs):
super(DecryptPasswordInstanceForm, self).__init__(request,
*args,
**kwargs)
instance_id = kwargs.get('initial', {}).get('instance_id')
self.fields['instance_id'].initial = instance_id
keypair_name = kwargs.get('initial', {}).get('keypair_name')
self.fields['keypair_name'].initial = keypair_name
try:
result = api.nova.get_password(request, instance_id)
if not result:
_unavailable = _("Instance Password is not set"
" or is not yet available")
self.fields['encrypted_password'].initial = _unavailable
else:
self.fields['encrypted_password'].initial = result
self.fields['private_key_file'] = forms.FileField(
label=_('Private Key File'),
widget=forms.FileInput())
self.fields['private_key'] = forms.CharField(
widget=forms.widgets.Textarea(),
label=_("OR Copy/Paste your Private Key"))
_attrs = {'readonly': 'readonly'}
self.fields['decrypted_password'] = forms.CharField(
widget=forms.widgets.TextInput(_attrs),
label=_("Password"),
required=False)
except Exception:
redirect = reverse('horizon:project:instances:index')
_error = _("Unable to retrieve instance password.")
exceptions.handle(request, _error, redirect=redirect)
def handle(self, request, data):
return True
class AttachInterface(forms.SelfHandlingForm):
instance_id = forms.CharField(widget=forms.HiddenInput())
network = forms.ChoiceField(label=_("Network"))
def __init__(self, request, *args, **kwargs):
super(AttachInterface, self).__init__(request, *args, **kwargs)
instance_id = kwargs.get('initial', {}).get('instance_id')
self.fields['instance_id'].initial = instance_id
networks = instance_utils.network_field_data(request,
include_empty_option=True)
self.fields['network'].choices = networks
def handle(self, request, data):
instance = data.get('instance_id')
network = data.get('network')
try:
api.nova.interface_attach(request, instance, net_id=network)
msg = _('Attaching interface for instance %s.') % instance
messages.success(request, msg)
except Exception:
redirect = reverse('horizon:project:instances:index')
exceptions.handle(request, _("Unable to attach interface."),
redirect=redirect)
return True
class DetachInterface(forms.SelfHandlingForm):
instance_id = forms.CharField(widget=forms.HiddenInput())
port = forms.ChoiceField(label=_("Port"))
def __init__(self, request, *args, **kwargs):
super(DetachInterface, self).__init__(request, *args, **kwargs)
instance_id = kwargs.get('initial', {}).get('instance_id')
self.fields['instance_id'].initial = instance_id
ports = []
try:
ports = api.neutron.port_list(request, device_id=instance_id)
except Exception:
exceptions.handle(request, _('Unable to retrieve ports '
'information.'))
choices = []
for port in ports:
ips = []
for ip in port.fixed_ips:
ips.append(ip['ip_address'])
choices.append((port.id, ','.join(ips) or port.id))
if choices:
choices.insert(0, ("", _("Select Port")))
else:
choices.insert(0, ("", _("No Ports available")))
self.fields['port'].choices = choices
def handle(self, request, data):
instance = data.get('instance_id')
port = data.get('port')
try:
api.nova.interface_detach(request, instance, port)
msg = _('Detached interface %(port)s for instance '
'%(instance)s.') % {'port': port, 'instance': instance}
messages.success(request, msg)
except Exception:
redirect = reverse('horizon:project:instances:index')
exceptions.handle(request, _("Unable to detach interface."),
redirect=redirect)
return True