Plan edit - change resource and parameters
User is unable to update the Protection Plan from the dashboard - updating name, status, resources and parameters. Change-Id: I5dfcc9507689a27d1a6bfdc9ca8f9f4711ba797a Closes-Bug: #1643338
This commit is contained in:
parent
f3eec93b83
commit
d3f3c06a05
|
@ -22,6 +22,9 @@ from horizon import messages
|
|||
import json
|
||||
from karbor_dashboard.api import karbor as karborclient
|
||||
|
||||
STATUS_CHOICE = [("suspended", "suspended"),
|
||||
("started", "started")]
|
||||
|
||||
|
||||
class CreateProtectionPlanForm(horizon_forms.SelfHandlingForm):
|
||||
name = forms.CharField(label=_("Name"))
|
||||
|
@ -78,6 +81,50 @@ class CreateProtectionPlanForm(horizon_forms.SelfHandlingForm):
|
|||
exceptions.handle(request, _('Unable to create protection plan.'))
|
||||
|
||||
|
||||
class UpdateProtectionPlanForm(horizon_forms.SelfHandlingForm):
|
||||
name = forms.CharField(label=_("Name"), max_length=255, required=False)
|
||||
status = forms.ChoiceField(label=_('Status'),
|
||||
choices=STATUS_CHOICE,
|
||||
widget=forms.Select(attrs={
|
||||
'class': 'switchable'}))
|
||||
plan = forms.CharField(
|
||||
widget=forms.HiddenInput(attrs={"class": "plan"}))
|
||||
provider = forms.CharField(
|
||||
widget=forms.HiddenInput(attrs={"class": "provider"}))
|
||||
resources = forms.CharField(
|
||||
widget=forms.HiddenInput(attrs={"class": "resources"}))
|
||||
parameters = forms.CharField(
|
||||
widget=forms.HiddenInput(attrs={"class": "parameters"}))
|
||||
|
||||
def handle(self, request, data):
|
||||
plan_id = self.initial['plan_id']
|
||||
status = data["status"]
|
||||
data_ = {"status": status}
|
||||
|
||||
name = data["name"]
|
||||
if name:
|
||||
data_.update({"name": name})
|
||||
|
||||
resources = json.loads(data["resources"])
|
||||
if resources:
|
||||
resources_ = []
|
||||
for resource in resources:
|
||||
if resource not in resources_:
|
||||
resources_.append(resource)
|
||||
data_.update({"resources": resources_})
|
||||
|
||||
try:
|
||||
new_plan = karborclient.plan_update(request,
|
||||
plan_id,
|
||||
data_)
|
||||
messages.success(request,
|
||||
_("Protection Plan updated successfully."))
|
||||
return new_plan
|
||||
except Exception as e:
|
||||
msg = _('Unable to update protection plan. ') + e.message
|
||||
exceptions.handle(request, msg)
|
||||
|
||||
|
||||
class ScheduleProtectForm(horizon_forms.SelfHandlingForm):
|
||||
id = forms.CharField(label=_("ID"), widget=forms.HiddenInput)
|
||||
name = forms.CharField(label=_("Name"), widget=forms.HiddenInput)
|
||||
|
|
|
@ -43,6 +43,16 @@ class ScheduleProtectLink(tables.LinkAction):
|
|||
return True
|
||||
|
||||
|
||||
class EditPlanLink(tables.LinkAction):
|
||||
name = "editplan"
|
||||
verbose_name = _("Edit Plan")
|
||||
url = "horizon:karbor:protectionplans:update"
|
||||
classes = ("ajax-modal",)
|
||||
|
||||
def allowed(self, request, protectionplan):
|
||||
return True
|
||||
|
||||
|
||||
class ProtectNowLink(tables.Action):
|
||||
name = "protectnow"
|
||||
verbose_name = _("Protect Now")
|
||||
|
@ -110,7 +120,7 @@ class ProtectionPlansTable(tables.DataTable):
|
|||
class Meta(object):
|
||||
name = 'protectionplans'
|
||||
verbose_name = _('Protection Plans')
|
||||
row_actions = (ScheduleProtectLink, ProtectNowLink,
|
||||
row_actions = (ScheduleProtectLink, EditPlanLink, ProtectNowLink,
|
||||
DeleteProtectionPlansAction)
|
||||
table_actions = (ProtectionPlanFilterAction, CreateProtectionPlanLink,
|
||||
DeleteProtectionPlansAction)
|
||||
|
|
|
@ -23,4 +23,6 @@ urlpatterns = [
|
|||
views.ScheduleProtectView.as_view(), name='scheduleprotect'),
|
||||
url(r'^(?P<plan_id>[^/]+)/detail/$',
|
||||
views.DetailView.as_view(), name='detail'),
|
||||
url(r'^(?P<plan_id>[^/]+)/update/$',
|
||||
views.UpdateView.as_view(), name='update'),
|
||||
]
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import uuid
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -26,7 +29,6 @@ from karbor_dashboard.api import karbor as karborclient
|
|||
from karbor_dashboard.protectionplans import forms
|
||||
from karbor_dashboard.protectionplans import tables
|
||||
from karborclient.v1 import protectables
|
||||
import uuid
|
||||
|
||||
|
||||
class IndexView(horizon_tables.DataTableView):
|
||||
|
@ -123,6 +125,87 @@ class CreateView(horizon_forms.ModalFormView):
|
|||
self.get_results([dependent], result.showid, results)
|
||||
|
||||
|
||||
class UpdateView(horizon_forms.ModalFormView):
|
||||
template_name = 'protectionplans/update.html'
|
||||
modal_header = _("Update Protection Plan")
|
||||
form_id = "update_protectionplan_form"
|
||||
form_class = forms.UpdateProtectionPlanForm
|
||||
submit_label = _("Update Protection Plan")
|
||||
submit_url = "horizon:karbor:protectionplans:update"
|
||||
success_url = reverse_lazy('horizon:karbor:protectionplans:index')
|
||||
page_title = _("Update Protection Plan")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpdateView, self).get_context_data(**kwargs)
|
||||
context["instances"] = self.get_protectable_objects()
|
||||
args = (self.kwargs['plan_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_protectable_objects(self):
|
||||
try:
|
||||
instances = karborclient.protectable_list_instances(
|
||||
self.request, "OS::Keystone::Project")
|
||||
results = []
|
||||
self.get_results(instances, None, results)
|
||||
return results
|
||||
except Exception:
|
||||
exceptions.handle(
|
||||
self.request,
|
||||
_('Unable to retrieve protection resources.'),
|
||||
redirect=reverse("horizon:karbor:protectionplans:index"))
|
||||
|
||||
def get_results(self, instances, showparentid, results):
|
||||
for instance in instances:
|
||||
if instance is not None:
|
||||
resource = {}
|
||||
resource["id"] = instance.id
|
||||
resource["type"] = instance.type
|
||||
resource["name"] = instance.name
|
||||
resource["showid"] = str(uuid.uuid4())
|
||||
resource["showparentid"] = showparentid
|
||||
result = protectables.Instances(self, resource)
|
||||
results.append(result)
|
||||
|
||||
for dependent_resource in instance.dependent_resources:
|
||||
if dependent_resource is not None:
|
||||
dependent = karborclient.protectable_get_instance(
|
||||
self.request,
|
||||
dependent_resource["type"],
|
||||
dependent_resource["id"])
|
||||
self.get_results([dependent], result.showid, results)
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_plan_object(self, *args, **kwargs):
|
||||
plan_id = self.kwargs['plan_id']
|
||||
try:
|
||||
return karborclient.plan_get(self.request, plan_id)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:karbor:protectionplans:index")
|
||||
msg = _('Unable to retrieve protection plan details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_provider_object(self, provider_id):
|
||||
try:
|
||||
return karborclient.provider_get(self.request, provider_id)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:karbor:protectionplans:index")
|
||||
msg = _('Unable to retrieve provider details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
initial = super(UpdateView, self).get_initial()
|
||||
plan = self.get_plan_object()
|
||||
provider = self.get_provider_object(plan.provider_id)
|
||||
initial.update({'plan_id': self.kwargs['plan_id'],
|
||||
'name': getattr(plan, 'name', ''),
|
||||
'plan': json.dumps(plan._info),
|
||||
'provider': json.dumps(provider._info)})
|
||||
return initial
|
||||
|
||||
|
||||
class ScheduleProtectView(horizon_forms.ModalFormView):
|
||||
template_name = 'protectionplans/scheduleprotect.html'
|
||||
modal_header = _("Schedule Protect")
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/* Copyright (c) 2016 Huawei, 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.
|
||||
*/
|
||||
|
||||
/* set the children check */
|
||||
function setChecked(node, isChecked) {
|
||||
if(isChecked) {
|
||||
node.row.find("input[type=checkbox]").prop("checked", true);
|
||||
}
|
||||
else {
|
||||
node.row.find("input[type=checkbox]").removeAttr("checked");
|
||||
}
|
||||
for(var i = 0; i<node.children.length;i++) {
|
||||
var resourceChild = node.children[i];
|
||||
setChecked(resourceChild, isChecked);
|
||||
}
|
||||
}
|
||||
|
||||
/* set the choose resources */
|
||||
function setProtectedResource() {
|
||||
var resources = [];
|
||||
var cbResources = $(".cbresource:checked");
|
||||
var provider = getProvider($("select[name='provider_id']").val());
|
||||
var parameters = $.Karbor.getResourceDefaultParameters(provider, "options_schema");
|
||||
if(cbResources != null) {
|
||||
cbResources.each(function() {
|
||||
var cbResource = $(this);
|
||||
var resource = {};
|
||||
resource.id = cbResource.closest("tr").attr("resource-id");
|
||||
resource.type = cbResource.closest("td").next().find("span").html();
|
||||
resource.name = cbResource.closest("span").nextAll("span.spanresource").eq(0).html();
|
||||
resources.push(resource);
|
||||
|
||||
var parameterbtn = cbResource.closest("tr").find(".editparameters");
|
||||
var userdata = parameterbtn.data("userdata");
|
||||
if(userdata!=null) {
|
||||
parameters[resource.type + "#" + resource.id] = userdata;
|
||||
}
|
||||
});
|
||||
}
|
||||
$(".resources").val(angular.toJson(resources));
|
||||
$(".parameters").val(angular.toJson(parameters));
|
||||
}
|
||||
|
||||
horizon.protectionplans_update = {
|
||||
/* init create plan dialog */
|
||||
init: function(){
|
||||
/* init resource tree */
|
||||
$("#protectionplanUpdateResource").treetable({ expandable: true });
|
||||
|
||||
/* init plan resources*/
|
||||
(function(){
|
||||
plan = $.parseJSON($(".plan").val());
|
||||
if(plan.resources != null){
|
||||
resources = plan.resources
|
||||
$(resources).each(function() {
|
||||
resource_id = this.id
|
||||
node = $("#protectionplanUpdateResource").find("tr[resource-id='"+ resource_id +"']");
|
||||
node.find("input[type=checkbox]").prop("checked", true);
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
/* init protection provider */
|
||||
(function() {
|
||||
provider = $.parseJSON($(".provider").val());
|
||||
$("#protectionplanUpdateResource").find("input[resourcetype]").data("schema", null);
|
||||
$("#protectionplanUpdateResource").find("input[resourcetype]").data("userdata", null);
|
||||
if(provider != null) {
|
||||
if(provider.extended_info_schema != null) {
|
||||
var result = provider.extended_info_schema['options_schema'];
|
||||
for(var r in result) {
|
||||
$("#protectionplanUpdateResource").find("input[resourcetype='" + r + "']").data("schema", result[r]);
|
||||
$("#protectionplanUpdateResource").find("input[resourcetype='" + r + "']").data("userdata", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/* live resource check event */
|
||||
$(document).on('click', ".cbresource", function() {
|
||||
var tr = $(this).closest("tr");
|
||||
var node = $("#protectionplanUpdateResource").treetable("node", tr.attr("data-tt-id"));
|
||||
setChecked(node, $(this).is(":checked"));
|
||||
});
|
||||
|
||||
/* live resource parameters event */
|
||||
$(document).on('click',".editparameters", function() {
|
||||
var schema = $(this).data("schema");
|
||||
var userdata = $(this).data("userdata");
|
||||
var resourceid = $(this).closest("tr").attr("resource-id");
|
||||
if(schema != null) {
|
||||
var exist_ui_dialogs = $("body").has(".ui-dialog");
|
||||
if(exist_ui_dialogs.length == 0){
|
||||
var dialog_data = $.Karbor.createDialog(schema, userdata, resourceid);
|
||||
$.Karbor.openDialog(dialog_data, "#parametersdialog", "div.dialog_wrapper");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* bind parameters dialog save button event */
|
||||
$(document).on('click', "#parametersdialog .btn.btn-primary", function() {
|
||||
var flag = $.Karbor.check_required($("#parametersdialog"));
|
||||
if(flag) {
|
||||
var resourceid = $("#parametersdialog .modal-body").attr("resourceid");
|
||||
var form_controls = $("#parametersdialog .modal-body .form-control");
|
||||
var userdata = $.Karbor.getDynamicValue(form_controls);
|
||||
$("#protectionplanUpdateResource").find("tr[resource-id='" + resourceid + "']")
|
||||
.find(".editparameters")
|
||||
.data("userdata", userdata);
|
||||
$.Karbor.closeDialog("#parametersdialog");
|
||||
}
|
||||
});
|
||||
|
||||
/* bind create button event */
|
||||
$(".btn-primary.save").bind("click", function() {
|
||||
setProtectedResource();
|
||||
return true;
|
||||
});
|
||||
|
||||
/* bind parameters dialog cancel button event */
|
||||
$(document).on('click', "#parametersdialog .btn.cancel", function() {
|
||||
$.Karbor.closeDialog("#parametersdialog");
|
||||
});
|
||||
|
||||
/* bind parameters dialog close button event */
|
||||
$(document).on('click', "#parametersdialog a.close", function() {
|
||||
$.Karbor.closeDialog("#parametersdialog");
|
||||
});
|
||||
|
||||
}
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load compress %}
|
||||
|
||||
{% block modal-body %}
|
||||
|
||||
{% block css %}
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" href="{% static 'karbordashboard/css/jquery.treetable.css' %}">
|
||||
{% endcompress %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
<div class="left" style="width:100%">
|
||||
<fieldset>
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</fieldset>
|
||||
<div class="table_wrapper">
|
||||
<table id="protectionplanUpdateResource" class="{% block table_css_classes %}table table-striped datatable {{ table.css_classes }}{% endblock %}">
|
||||
<thead>
|
||||
<tr class="table_column_header">
|
||||
<th {{ column.attr_string|safe }}>
|
||||
Resource Name
|
||||
</th>
|
||||
<th {{ column.attr_string|safe }}>
|
||||
Resource Type
|
||||
</th>
|
||||
<th {{ column.attr_string|safe }}>
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for instance in instances %}
|
||||
<tr data-tt-id="{{ instance.showid }}"
|
||||
resource-id="{{ instance.id }}"
|
||||
{% if instance.showparentid != None %}
|
||||
data-tt-parent-id="{{ instance.showparentid }}"
|
||||
{% endif %}>
|
||||
<td>
|
||||
<span class="spanresource"><input type="checkbox" class="cbresource"/></span>
|
||||
<span class="logoresource"></span>
|
||||
<span class="spanresource">{{instance.name}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="spanresource">{{instance.type}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="button" class="btn btn-default editparameters" value="Edit Parameters" resourcetype="{{instance.type}}">
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="dialog_wrapper"></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
(window.$ || window.addHorizonLoadEvent)(function () {
|
||||
horizon.protectionplans_update.init();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-footer %}
|
||||
<a class="btn btn-default cancel">Cancel</a>
|
||||
<input class="btn btn-primary save" type="submit" value="Save">
|
||||
{% endblock %}
|
|
@ -0,0 +1,10 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Update Protection Plan" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'protectionplans/_update.html' %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue