Implement update host
Implemented update host functionality. Also added test case for update host. Partial-Implements: blueprint masakari-dashboard Change-Id: I197440d069a1b5b49a234da8f05a01d45f222f2e
This commit is contained in:
parent
bef761d1d9
commit
f463ab19f8
|
@ -153,6 +153,11 @@ def delete_host(request, host_id, segment_id):
|
||||||
host_id, segment_id, False)
|
host_id, segment_id, False)
|
||||||
|
|
||||||
|
|
||||||
def get_host(request, segment_id, host_id):
|
def update_host(request, host_uuid, failover_segment_id, fields_to_update):
|
||||||
"""return single host."""
|
return openstack_connection(request).update_host(
|
||||||
|
host_uuid, failover_segment_id, **fields_to_update)
|
||||||
|
|
||||||
|
|
||||||
|
def get_host(request, host_id, segment_id):
|
||||||
|
"""return single host """
|
||||||
return openstack_connection(request).get_host(host_id, segment_id)
|
return openstack_connection(request).get_host(host_id, segment_id)
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
# Copyright (c) 2018 NTT DATA
|
||||||
|
#
|
||||||
|
# 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.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
|
from horizon import messages
|
||||||
|
|
||||||
|
from masakaridashboard.api import api
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateHostForm(forms.SelfHandlingForm):
|
||||||
|
|
||||||
|
uuid = forms.CharField(widget=forms.HiddenInput())
|
||||||
|
failover_segment_id = forms.CharField(widget=forms.HiddenInput())
|
||||||
|
name = forms.CharField(
|
||||||
|
label=_('Host Name'),
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||||
|
reserved = forms.ChoiceField(
|
||||||
|
label=_('Reserved'),
|
||||||
|
choices=[('False', 'False'),
|
||||||
|
('True', 'True')],
|
||||||
|
widget=forms.Select(
|
||||||
|
attrs={'class': 'switchable',
|
||||||
|
'data-slug': 'available host'}),
|
||||||
|
required=False)
|
||||||
|
type = forms.CharField(
|
||||||
|
label=_('Type'),
|
||||||
|
widget=forms.TextInput(attrs={'maxlength': 255}))
|
||||||
|
control_attributes = forms.CharField(
|
||||||
|
label=_('Control Attribute'),
|
||||||
|
widget=forms.TextInput())
|
||||||
|
on_maintenance = forms.ChoiceField(
|
||||||
|
label=_('On Maintenance'),
|
||||||
|
choices=[('False', 'False'),
|
||||||
|
('True', 'True')],
|
||||||
|
widget=forms.Select(
|
||||||
|
attrs={'class': 'switchable',
|
||||||
|
'data-slug': 'available host'}),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, request, data):
|
||||||
|
try:
|
||||||
|
attrs = {'name': data['name'],
|
||||||
|
'reserved': data['reserved'],
|
||||||
|
'type': data['type'],
|
||||||
|
'control_attributes': data['control_attributes'],
|
||||||
|
'on_maintenance': data['on_maintenance']}
|
||||||
|
api.update_host(request, data['uuid'],
|
||||||
|
data["failover_segment_id"], attrs)
|
||||||
|
msg = _('Successfully updated segment.')
|
||||||
|
messages.success(request, msg)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Failed to update host.')
|
||||||
|
redirect = reverse('horizon:masakaridashboard:hosts:index')
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
return True
|
|
@ -64,6 +64,18 @@ class DeleteHost(tables.DeleteAction):
|
||||||
exceptions.handle(self.request, msg, redirect=redirect)
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateHost(tables.LinkAction):
|
||||||
|
|
||||||
|
name = "update"
|
||||||
|
verbose_name = _("Update Host")
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
|
||||||
|
def get_link_url(self, datum):
|
||||||
|
host_id = datum.uuid+','+datum.failover_segment_id
|
||||||
|
url = "horizon:masakaridashboard:hosts:update"
|
||||||
|
return reverse(url, args=[host_id])
|
||||||
|
|
||||||
|
|
||||||
class HostTable(tables.DataTable):
|
class HostTable(tables.DataTable):
|
||||||
|
|
||||||
name = tables.Column('name', verbose_name=_("Name"),
|
name = tables.Column('name', verbose_name=_("Name"),
|
||||||
|
@ -71,8 +83,7 @@ class HostTable(tables.DataTable):
|
||||||
uuid = tables.Column('uuid', verbose_name=_("UUID"))
|
uuid = tables.Column('uuid', verbose_name=_("UUID"))
|
||||||
reserved = tables.Column(
|
reserved = tables.Column(
|
||||||
'reserved', verbose_name=_("Reserved"))
|
'reserved', verbose_name=_("Reserved"))
|
||||||
type = tables.Column(
|
type = tables.WrappingColumn('type', verbose_name=_("Type"))
|
||||||
'type', verbose_name=_("Type"))
|
|
||||||
control_attributes = tables.Column(
|
control_attributes = tables.Column(
|
||||||
'control_attributes', verbose_name=_(
|
'control_attributes', verbose_name=_(
|
||||||
"Control Attribute"), truncate=40)
|
"Control Attribute"), truncate=40)
|
||||||
|
@ -89,3 +100,4 @@ class HostTable(tables.DataTable):
|
||||||
name = "host"
|
name = "host"
|
||||||
verbose_name = _("Host")
|
verbose_name = _("Host")
|
||||||
table_actions = (HostFilterAction, DeleteHost)
|
table_actions = (HostFilterAction, DeleteHost)
|
||||||
|
row_actions = (UpdateHost,)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{% extends "horizon/common/_modal_form.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block modal-body-right %}
|
||||||
|
<h3>{% trans "Description:" %}</h3>
|
||||||
|
<p>{% trans "Modify reserved, type, on_maintenance and control_attributes of a host." %}</p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Update Host" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include 'masakaridashboard/hosts/_update.html' %}
|
||||||
|
{% endblock %}
|
|
@ -35,6 +35,7 @@ class HostTest(test.TestCase):
|
||||||
return_value=hosts):
|
return_value=hosts):
|
||||||
res = self.client.get(INDEX_URL)
|
res = self.client.get(INDEX_URL)
|
||||||
self.assertTemplateUsed(res, 'masakaridashboard/hosts/index.html')
|
self.assertTemplateUsed(res, 'masakaridashboard/hosts/index.html')
|
||||||
|
self.assertEqual(res.status_code, 200)
|
||||||
|
|
||||||
def test_create_post(self):
|
def test_create_post(self):
|
||||||
segment = self.masakari_segment.list()
|
segment = self.masakari_segment.list()
|
||||||
|
@ -47,9 +48,9 @@ class HostTest(test.TestCase):
|
||||||
'segment_name': segment[0].name,
|
'segment_name': segment[0].name,
|
||||||
'name': host.name,
|
'name': host.name,
|
||||||
'type': host.type,
|
'type': host.type,
|
||||||
'reserved': '1',
|
'reserved': host.reserved,
|
||||||
'control_attributes': host.control_attributes,
|
'control_attributes': host.control_attributes,
|
||||||
'on_maintenance': '0'
|
'on_maintenance': host.on_maintenance
|
||||||
}
|
}
|
||||||
with mock.patch('masakaridashboard.api.api.segment_list',
|
with mock.patch('masakaridashboard.api.api.segment_list',
|
||||||
return_value=segment), mock.patch(
|
return_value=segment), mock.patch(
|
||||||
|
@ -107,3 +108,45 @@ class HostTest(test.TestCase):
|
||||||
self.assertTemplateUsed(res, 'horizon/common/_detail.html')
|
self.assertTemplateUsed(res, 'horizon/common/_detail.html')
|
||||||
self.assertTemplateUsed(
|
self.assertTemplateUsed(
|
||||||
res, 'masakaridashboard/hosts/_detail_overview.html')
|
res, 'masakaridashboard/hosts/_detail_overview.html')
|
||||||
|
|
||||||
|
def test_update(self):
|
||||||
|
host_to_update = self.masakari_host.list()[0]
|
||||||
|
id_to_update = (
|
||||||
|
host_to_update.uuid+','+host_to_update.failover_segment_id)
|
||||||
|
update_url = reverse('horizon:masakaridashboard:hosts:update',
|
||||||
|
args=[id_to_update])
|
||||||
|
host_to_update.control_attributes = 'fake'
|
||||||
|
form_data = {
|
||||||
|
'failover_segment_id': host_to_update.failover_segment_id,
|
||||||
|
'uuid': host_to_update.uuid,
|
||||||
|
'name': host_to_update.name,
|
||||||
|
'type': host_to_update.type,
|
||||||
|
'reserved': host_to_update.reserved,
|
||||||
|
'control_attributes': host_to_update.control_attributes,
|
||||||
|
'on_maintenance': host_to_update.on_maintenance
|
||||||
|
}
|
||||||
|
with mock.patch(
|
||||||
|
'masakaridashboard.api.api.get_host',
|
||||||
|
return_value=self.masakari_host.list()[0]), mock.patch(
|
||||||
|
'masakaridashboard.api.api.update_host',
|
||||||
|
return_value=host_to_update) as mocked_update:
|
||||||
|
res = self.client.post(update_url, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertEqual(res.status_code, 302)
|
||||||
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
|
fields_to_update = {
|
||||||
|
'name': host_to_update.name,
|
||||||
|
'type': host_to_update.type,
|
||||||
|
'reserved': host_to_update.reserved,
|
||||||
|
'control_attributes': host_to_update.control_attributes,
|
||||||
|
'on_maintenance': host_to_update.on_maintenance
|
||||||
|
}
|
||||||
|
|
||||||
|
mocked_update.assert_called_once_with(
|
||||||
|
mock.ANY,
|
||||||
|
host_to_update.uuid,
|
||||||
|
host_to_update.failover_segment_id,
|
||||||
|
fields_to_update
|
||||||
|
)
|
||||||
|
|
|
@ -21,4 +21,5 @@ HOST = r'^(?P<host_id>[^/]+)/%s$'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
url(HOST % 'detail', views.DetailView.as_view(), name='detail'),
|
url(HOST % 'detail', views.DetailView.as_view(), name='detail'),
|
||||||
|
url(HOST % 'update', views.UpdateView.as_view(), name='update'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,14 +14,17 @@
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.core.urlresolvers import reverse_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
from horizon.utils import memoized
|
from horizon.utils import memoized
|
||||||
|
|
||||||
from masakaridashboard.api import api
|
from masakaridashboard.api import api
|
||||||
|
from masakaridashboard.hosts import forms as host_forms
|
||||||
from masakaridashboard.hosts import tables as masakari_tab
|
from masakaridashboard.hosts import tables as masakari_tab
|
||||||
from masakaridashboard.hosts import tabs as host_tab
|
from masakaridashboard.hosts import tabs as host_tab
|
||||||
|
|
||||||
|
@ -74,7 +77,10 @@ class DetailView(tabs.TabbedTableView):
|
||||||
segment_id = row_data[1]
|
segment_id = row_data[1]
|
||||||
host_id = row_data[0]
|
host_id = row_data[0]
|
||||||
try:
|
try:
|
||||||
host = api.get_host(self.request, segment_id, host_id)
|
row_data = self.kwargs['host_id'].split(',')
|
||||||
|
segment_id = row_data[1]
|
||||||
|
host_id = row_data[0]
|
||||||
|
host = api.get_host(self.request, host_id, segment_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = _('Unable to get host "%s".') % host_id
|
msg = _('Unable to get host "%s".') % host_id
|
||||||
redirect = reverse('horizon:masakaridashboard:hosts:index')
|
redirect = reverse('horizon:masakaridashboard:hosts:index')
|
||||||
|
@ -88,3 +94,47 @@ class DetailView(tabs.TabbedTableView):
|
||||||
def get_tabs(self, request, *args, **kwargs):
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
host = self.get_data()
|
host = self.get_data()
|
||||||
return self.tab_group_class(request, host=host, **kwargs)
|
return self.tab_group_class(request, host=host, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateView(forms.ModalFormView):
|
||||||
|
template_name = 'masakaridashboard/hosts/update.html'
|
||||||
|
modal_header = _("Update Host")
|
||||||
|
form_id = "update_host"
|
||||||
|
form_class = host_forms.UpdateHostForm
|
||||||
|
submit_label = _("Update")
|
||||||
|
submit_url = "horizon:masakaridashboard:hosts:update"
|
||||||
|
success_url = reverse_lazy("horizon:masakaridashboard:hosts:index")
|
||||||
|
page_title = _("Update Host")
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_object(self):
|
||||||
|
try:
|
||||||
|
row_data = self.kwargs['host_id'].split(',')
|
||||||
|
host_id = row_data[0]
|
||||||
|
segment_id = row_data[1]
|
||||||
|
host = api.get_host(self.request, host_id, segment_id)
|
||||||
|
return host
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve host.')
|
||||||
|
redirect = reverse('horizon:masakaridashboard:hosts:index')
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(UpdateView, self).get_context_data(**kwargs)
|
||||||
|
context['submit_url'] = reverse(
|
||||||
|
self.submit_url,
|
||||||
|
args=[self.kwargs['host_id']]
|
||||||
|
)
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_initial(self, **kwargs):
|
||||||
|
host = self.get_object()
|
||||||
|
|
||||||
|
return {'name': host.name,
|
||||||
|
'reserved': host.reserved,
|
||||||
|
'type': host.type,
|
||||||
|
'control_attributes': host.control_attributes,
|
||||||
|
'on_maintenance': host.on_maintenance,
|
||||||
|
'uuid': host.uuid,
|
||||||
|
'failover_segment_id': host.failover_segment_id}
|
||||||
|
|
|
@ -118,8 +118,8 @@ class AddHostForm(forms.SelfHandlingForm):
|
||||||
choices=[])
|
choices=[])
|
||||||
reserved = forms.ChoiceField(
|
reserved = forms.ChoiceField(
|
||||||
label=_('Reserved'),
|
label=_('Reserved'),
|
||||||
choices=[('0', 'False'),
|
choices=[('False', 'False'),
|
||||||
('1', 'True')],
|
('True', 'True')],
|
||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
attrs={'class': 'switchable',
|
attrs={'class': 'switchable',
|
||||||
'data-slug': 'available host'}),
|
'data-slug': 'available host'}),
|
||||||
|
@ -136,8 +136,8 @@ class AddHostForm(forms.SelfHandlingForm):
|
||||||
help_text=_("Attributes to control host."))
|
help_text=_("Attributes to control host."))
|
||||||
on_maintenance = forms.ChoiceField(
|
on_maintenance = forms.ChoiceField(
|
||||||
label=_('On Maintenance'),
|
label=_('On Maintenance'),
|
||||||
choices=[('0', 'False'),
|
choices=[('False', 'False'),
|
||||||
('1', 'True')],
|
('True', 'True')],
|
||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
attrs={'class': 'switchable',
|
attrs={'class': 'switchable',
|
||||||
'data-slug': 'available host'}),
|
'data-slug': 'available host'}),
|
||||||
|
|
|
@ -44,10 +44,10 @@ def data(TEST):
|
||||||
TEST.masakari_host = test_data_utils.TestDataContainer()
|
TEST.masakari_host = test_data_utils.TestDataContainer()
|
||||||
|
|
||||||
host1 = host.Host(uuid=uuidsentinel.host1, name="test",
|
host1 = host.Host(uuid=uuidsentinel.host1, name="test",
|
||||||
reserved=True, type='service',
|
reserved='True', type='service',
|
||||||
control_attributes='test',
|
control_attributes='test',
|
||||||
failover_segment_id=uuidsentinel.segment1,
|
failover_segment_id=uuidsentinel.segment1,
|
||||||
on_maintenance=False)
|
on_maintenance='False')
|
||||||
|
|
||||||
TEST.masakari_host.add(host1)
|
TEST.masakari_host.add(host1)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue