Add "add template" and "delete template" buttons to vitrage template
view. Story: 2002701 Task: 22536 Depends-On: I156ec1665d98f247f01a1b0a5adaf26ab1eb09ce Change-Id: If0cb54d7dfabda57491652c13ff203f6da982dba
This commit is contained in:
parent
470ae7d22d
commit
4ae81c30d4
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Added buttons for adding and removing templates in the template view.
|
@ -22,11 +22,12 @@ https://docs.openstack.org/horizon/latest/contributor/tutorials/plugin.html
|
||||
While interactions with the service can be handled in the views.py,
|
||||
isolating the logic is an established pattern in Horizon.
|
||||
"""
|
||||
|
||||
from horizon.utils.memoized import memoized # noqa
|
||||
import json
|
||||
from keystoneauth1.identity.generic.token import Token
|
||||
from keystoneauth1.session import Session
|
||||
from openstack_dashboard.api import base
|
||||
import tempfile
|
||||
from vitrageclient import client as vitrage_client
|
||||
|
||||
import logging
|
||||
@ -77,7 +78,22 @@ def rca(request, alarm_id, all_tenants='false'):
|
||||
all_tenants=all_tenants)
|
||||
|
||||
|
||||
def templates(request, template_id='all'):
|
||||
def template_show(request, template_id='all'):
|
||||
if template_id == 'all':
|
||||
return vitrageclient(request).template.list()
|
||||
return vitrageclient(request).template.show(template_id)
|
||||
|
||||
|
||||
def template_delete(request, template_id):
|
||||
return vitrageclient(request).template.delete(template_id)
|
||||
|
||||
|
||||
def template_add(request):
|
||||
template = json.loads(request.body)
|
||||
type = template.get('type')
|
||||
with tempfile.NamedTemporaryFile(suffix='.yaml') as temp:
|
||||
temp.write(template.get('template'))
|
||||
temp.flush()
|
||||
temp.seek(0)
|
||||
response = vitrageclient(request).template.add(temp.name, type)
|
||||
return response
|
||||
|
@ -135,5 +135,24 @@ class Templates(generic.View):
|
||||
|
||||
The result is a template object.
|
||||
"""
|
||||
return vitrage.template_show(request, template_id)
|
||||
|
||||
return vitrage.templates(request, template_id)
|
||||
@rest_utils.ajax()
|
||||
def delete(self, request, template_id):
|
||||
"""Delete a single template with the vitrage id.
|
||||
|
||||
:param template_id the id of the vitrage template
|
||||
"""
|
||||
return vitrage.template_delete(request, template_id)
|
||||
|
||||
@rest_utils.ajax()
|
||||
def post(self, request, **kwargs):
|
||||
"""Add a single template.
|
||||
|
||||
request.body holds template in format:
|
||||
{template: template_string
|
||||
type: template_type}
|
||||
|
||||
"""
|
||||
|
||||
return vitrage.template_add(request)
|
||||
|
@ -17,7 +17,9 @@
|
||||
getTopology: getTopology,
|
||||
getAlarms: getAlarms,
|
||||
getRca: getRca,
|
||||
getTemplates: getTemplates
|
||||
getTemplates: getTemplates,
|
||||
deleteTemplate: deleteTemplate,
|
||||
addTemplate: addTemplate
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -74,6 +76,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTemplate(template_id) {
|
||||
return apiService.delete('/api/vitrage/template/'+template_id)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to fetch the Vitrage Templates service.'));
|
||||
});
|
||||
}
|
||||
|
||||
function addTemplate(template, type) {
|
||||
var temp = { 'template' : template, 'type': type }
|
||||
return apiService.post('/api/vitrage/template/default/', temp)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to fetch the Vitrage Templates service.'));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}());
|
||||
|
@ -0,0 +1,22 @@
|
||||
<div class="template-container">
|
||||
<div class="controls">
|
||||
<i title="Close" class="fa fa-times" ng-click="templateList.closeModal()"></i>
|
||||
</div>
|
||||
<div style="margin:15px">
|
||||
<h2>Select template type:</h2>
|
||||
</div>
|
||||
<form>
|
||||
<div style="margin: 15px">
|
||||
<select class="form-control form-control-lg" id="typeSelect">
|
||||
<option selected="selected">Standard</option>
|
||||
<option>Definition</option>
|
||||
<option>Equivalence</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="margin: 15px">
|
||||
<button type="button" class="btn btn-primary" ng-click="templateList.submitModal()">
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -12,8 +12,10 @@
|
||||
|
||||
function show(modalOptions) {
|
||||
modalInstance = $uibModal.open(modalOptions);
|
||||
return modalInstance;
|
||||
}
|
||||
|
||||
//resolves the promise modalInstance.result
|
||||
function close() {
|
||||
if(modalInstance) {
|
||||
modalInstance.close();
|
||||
@ -21,9 +23,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
//rejects the promise modalInstance.result
|
||||
function dismiss() {
|
||||
if(modalInstance) {
|
||||
modalInstance.dismiss();
|
||||
modalInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
show: show,
|
||||
close: close
|
||||
close: close,
|
||||
dismiss: dismiss
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
@ -57,6 +57,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
function deleteTemplate(template_id) {
|
||||
|
||||
if (vitrageAPI) {
|
||||
return vitrageAPI.deleteTemplate(template_id)
|
||||
.then(function (data) {
|
||||
return data;
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function addTemplate(template, type) {
|
||||
|
||||
if (vitrageAPI) {
|
||||
return vitrageAPI.addTemplate(template, type)
|
||||
.then(function (data) {
|
||||
return data;
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getRootCauseAnalysis(alarm_id, adminState) {
|
||||
if (vitrageAPI) {
|
||||
@ -75,7 +103,9 @@
|
||||
getTopology: getTopology,
|
||||
getAlarms: getAlarms,
|
||||
getRootCauseAnalysis: getRootCauseAnalysis,
|
||||
getTemplates: getTemplates
|
||||
getTemplates: getTemplates,
|
||||
deleteTemplate: deleteTemplate,
|
||||
addTemplate: addTemplate
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
@ -7,13 +7,85 @@
|
||||
|
||||
TemplateListController.$inject = ['$scope', 'modalSrv', 'vitrageTopologySrv'];
|
||||
|
||||
function TemplateListController($scope, modalSrv, vitrageTopologySrv) {
|
||||
function TemplateListController($scope, modalSrv, vitrageTopologySrv)
|
||||
{
|
||||
var templateList = this;
|
||||
templateList.templates = [];
|
||||
templateList.itemplates = [];
|
||||
$scope.STATIC_URL = STATIC_URL;
|
||||
templateList.templates = [];
|
||||
|
||||
|
||||
templateList.closeModal = function() {
|
||||
if(templateList.file){
|
||||
delete templateList.file.name;
|
||||
}
|
||||
modalSrv.dismiss();
|
||||
}
|
||||
|
||||
templateList.submitModal = function() {
|
||||
modalSrv.close();
|
||||
}
|
||||
|
||||
templateList.uploadFile = function(file, errFile) {
|
||||
if (file) {
|
||||
var ending = file.name.split('.').pop();
|
||||
if(ending !== 'yml' && ending !== 'yaml') {
|
||||
horizon.toast.add("error", gettext("Invalid file type. Templates should be YAML files"));
|
||||
delete file.name;
|
||||
return;
|
||||
}
|
||||
|
||||
var modalOptions = {
|
||||
animation: true,
|
||||
templateUrl: STATIC_URL + 'dashboard/project/components/templateAdd/templateAddOptions.html',
|
||||
controller: 'TemplateListController',
|
||||
controllerAs: 'templateList',
|
||||
windowClass: 'modal-dialog-metadata',
|
||||
resolve: {file: function() {
|
||||
return file;
|
||||
}}
|
||||
};
|
||||
templateList.file = file;
|
||||
modalSrv.show(modalOptions).result.then(() => templateList.chooseType())
|
||||
}
|
||||
}
|
||||
|
||||
templateList.chooseType = function() {
|
||||
var e = document.getElementById("typeSelect");
|
||||
var type = e.options[e.selectedIndex].text.toLowerCase();
|
||||
var file = templateList.file;
|
||||
templateList.type = type;
|
||||
if (type !== "standard" && type !== "definition" && type !== "equivalence") {
|
||||
horizon.toast.add("error", gettext("Invalid type entered. Type is one of: standard, definition, equivalence"));
|
||||
delete file.name;
|
||||
return;
|
||||
}
|
||||
var r = new FileReader();
|
||||
r.onload = function(e) {
|
||||
var content = e.target.result;
|
||||
vitrageTopologySrv.addTemplate(content, type).then(function(result){
|
||||
getData();
|
||||
})
|
||||
.catch(function(){
|
||||
horizon.toast.add("error",gettext("Unable to add template"));
|
||||
return;
|
||||
});
|
||||
}
|
||||
r.catch = function() {
|
||||
horizon.toast.add("error",gettext("Unable to read file"));
|
||||
delete file.name;
|
||||
}
|
||||
try{
|
||||
r.readAsText(file);
|
||||
}
|
||||
catch(error){
|
||||
horizon.toast.add("error",gettext("Unable to read file"));
|
||||
delete file.name;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getData();
|
||||
|
||||
function getData() {
|
||||
@ -34,6 +106,15 @@
|
||||
|
||||
modalSrv.show(modalOptions);
|
||||
}
|
||||
|
||||
templateList.onDeleteClick = function(template) {
|
||||
vitrageTopologySrv.deleteTemplate(template.uuid).then(function(result){
|
||||
getData();
|
||||
})
|
||||
.catch(function(){
|
||||
horizon.toast.add("error", gettext("Unable to delete template"));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,16 @@
|
||||
<div class="template-list" ng-controller="TemplateListController as templateList">
|
||||
<div class="add-btn">
|
||||
<button class="btn btn-primary"
|
||||
type="file"
|
||||
id="add-template"
|
||||
ngf-select="templateList.uploadFile($file, $invalidFiles)"
|
||||
ngf-max-height="1000"
|
||||
accept="*"
|
||||
ngf-max-size="1MB">
|
||||
Add Template
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
|
||||
<table st-table='templateList.itemplates' st-safe-src="templateList.templates" class="table-striped table-rsp table-detail modern"
|
||||
@ -11,6 +23,7 @@
|
||||
<th st-sort="details">{$ 'Details' | translate $}</th>
|
||||
<th st-sort="timestamp">{$ 'Timestamp' | translate $}</th>
|
||||
<th>{$ 'Show' | translate $}</th>
|
||||
<th>{$ 'Delete' | translate $}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="5">
|
||||
@ -26,8 +39,9 @@
|
||||
<td>{$template.status$}</td>
|
||||
<td>{$template.type$}</td>
|
||||
<td>{$template["status details"]$}</td>
|
||||
<td><i class="fa fa-clock-o"></i> {$template.date | date:"yyyy-MM-dd HH:mm:ss"$}</td>
|
||||
<td><i class="fa fa-clock-o"></i> {$template.date | date:"yyyy-MM-dd hh:mm:ss"$}</td>
|
||||
<td ng-click="templateList.onShowClick(template)"><i class="fa fa-list"></i></td>
|
||||
<td ng-click="templateList.onDeleteClick(template)"><i class="fa fa-trash"></i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -7,4 +7,8 @@
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.add-btn{
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user