Merge "Support a host update operation"

This commit is contained in:
Zuul 2017-11-02 09:38:29 +00:00 committed by Gerrit Code Review
commit ee40700175
8 changed files with 201 additions and 2 deletions

View File

@ -124,6 +124,12 @@ def host_create(request, name, **kwargs):
return Host(host)
def host_update(request, host_id, values):
"""Update a host."""
host = blazarclient(request).host.update(host_id, values)
return Host(host)
def host_delete(request, host_id):
"""Delete a host."""
blazarclient(request).host.delete(host_id)

View File

@ -0,0 +1,64 @@
# 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 exceptions
from horizon import forms
from horizon import messages
from blazar_dashboard import api
LOG = logging.getLogger(__name__)
class UpdateForm(forms.SelfHandlingForm):
class Meta(object):
name = _('Update Host Parameters')
host_id = forms.CharField(
label=_('Host ID'), widget=forms.widgets.HiddenInput, required=True)
values = forms.CharField(
label=_("Values to Update"),
required=True,
help_text=_('Enter values to update in JSON'),
widget=forms.Textarea(
attrs={'rows': 5}),
max_length=511)
def handle(self, request, data):
try:
api.client.host_update(self.request, host_id=data.get('host_id'),
values=data.get('values'))
messages.success(request, _("Host was successfully updated."))
return True
except Exception as e:
LOG.error('Error updating host: %s', e)
exceptions.handle(request,
message="An error occurred while updating this"
" host: %s. Please try again." % e)
def clean(self):
cleaned_data = super(UpdateForm, self).clean()
values = cleaned_data.get('values')
try:
values = eval(values)
cleaned_data['values'] = values
except (SyntaxError, NameError):
raise forms.ValidationError(
_('Values must written in JSON')
)
return cleaned_data

View File

@ -26,6 +26,13 @@ class CreateHosts(tables.LinkAction):
icon = "plus"
class UpdateHost(tables.LinkAction):
name = "update"
verbose_name = _("Update Host")
url = "horizon:admin:hosts:update"
classes = ("btn-create", "ajax-modal")
class DeleteHost(tables.DeleteAction):
name = "delete"
data_type_singular = _("Host")
@ -66,4 +73,4 @@ class HostsTable(tables.DataTable):
name = "hosts"
verbose_name = _("Hosts")
table_actions = (CreateHosts, DeleteHost,)
row_actions = (DeleteHost,)
row_actions = (UpdateHost, DeleteHost,)

View File

@ -0,0 +1,24 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block form_id %}update_host{% endblock %}
{% block form_action %}{% url 'horizon:admin:hosts:update' host.id %}{% endblock %}
{% block modal_id %}update_host_modal{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description" %}:</h3>
<p>{% trans "Update extra capabilities of the host with the provided values." %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Update" %}" />
<a href="{% url 'horizon:admin:hosts:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Update Host" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Update Host") %}
{% endblock page_header %}
{% block main %}
{% include 'admin/hosts/_update.html' %}
{% endblock %}

View File

@ -27,6 +27,8 @@ DETAIL_TEMPLATE = 'admin/hosts/detail.html'
DETAIL_URL_BASE = 'horizon:admin:hosts:detail'
CREATE_URL = reverse('horizon:admin:hosts:create')
CREATE_TEMPLATE = 'admin/hosts/create.html'
UPDATE_URL_BASE = 'horizon:admin:hosts:update'
UPDATE_TEMPLATE = 'admin/hosts/update.html'
class HostsTests(test.BaseAdminViewTests):
@ -134,6 +136,53 @@ class HostsTests(test.BaseAdminViewTests):
self.assertMessageCount(success=(len(host_names) + 1))
self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({blazar_api.client: ('host_get', 'host_update')})
def test_update_host(self):
host = self.hosts.get(hypervisor_hostname='compute-1')
blazar_api.client.host_get(
IsA(http.HttpRequest),
host['id']
).AndReturn(host)
blazar_api.client.host_update(
IsA(http.HttpRequest),
host_id=host['id'],
values={"key": "updated"}
)
form_data = {
'host_id': host['id'],
'values': '{"key": "updated"}'
}
self.mox.ReplayAll()
res = self.client.post(reverse(UPDATE_URL_BASE, args=[host['id']]),
form_data)
self.assertNoFormErrors(res)
self.assertMessageCount(success=1)
self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({blazar_api.client: ('host_get', 'host_update')})
def test_update_host_error(self):
host = self.hosts.get(hypervisor_hostname='compute-1')
blazar_api.client.host_get(
IsA(http.HttpRequest),
host['id']
).AndReturn(host)
blazar_api.client.host_update(
IsA(http.HttpRequest),
host_id=host['id'],
values={"key": "updated"}
).AndRaise(self.exceptions.blazar)
form_data = {
'host_id': host['id'],
'values': '{"key": "updated"}'
}
self.mox.ReplayAll()
res = self.client.post(reverse(UPDATE_URL_BASE, args=[host['id']]),
form_data)
self.assertNoFormErrors(res)
self.assertContains(res, 'An error occurred while updating')
@test.create_stubs({blazar_api.client: ('host_list', 'host_delete')})
def test_delete_host(self):
hosts = self.hosts.list()

View File

@ -18,5 +18,7 @@ from blazar_dashboard.content.hosts import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^create/$', views.CreateView.as_view(), name='create'),
url(r'^(?P<host_id>[^/]+)/$', views.DetailView.as_view(), name='detail')
url(r'^(?P<host_id>[^/]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<host_id>[^/]+)/update$', views.UpdateView.as_view(),
name='update'),
]

View File

@ -10,13 +10,17 @@
# License for the specific language governing permissions and limitations
# under the License.
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import tables
from horizon import tabs
from horizon.utils import memoized
from horizon import workflows
from blazar_dashboard import api
from blazar_dashboard.content.hosts import forms as project_forms
from blazar_dashboard.content.hosts import tables as project_tables
from blazar_dashboard.content.hosts import tabs as project_tabs
from blazar_dashboard.content.hosts import workflows as project_workflows
@ -45,3 +49,35 @@ class CreateView(workflows.WorkflowView):
workflow_class = project_workflows.CreateHostsWorkflow
template_name = 'admin/hosts/create.html'
page_title = _("Create Hosts")
class UpdateView(forms.ModalFormView):
form_class = project_forms.UpdateForm
template_name = 'admin/hosts/update.html'
success_url = reverse_lazy('horizon:admin:hosts:index')
def get_initial(self):
initial = super(UpdateView, self).get_initial()
initial['host'] = self.get_object()
if initial['host']:
initial['host_id'] = initial['host'].id
initial['name'] = initial['host'].hypervisor_hostname
return initial
def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs)
context['host'] = self.get_object()
return context
@memoized.memoized_method
def get_object(self):
host_id = self.kwargs['host_id']
try:
host = api.client.host_get(self.request, host_id)
except Exception:
msg = _("Unable to retrieve host.")
redirect = reverse_lazy('horizon:admin:hosts:index')
exceptions.handle(self.request, msg, redirect=redirect)
return host