Commit f9aa89de by Sulyok Gábor

Fix javascript and integrate new backend

parent 9ab17d5f
......@@ -2,13 +2,14 @@ from .models import *
from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.db.models.loading import get_model
from django.db import transaction
from saltstackhelper import *
import os
class SettyController:
salthelper = SaltStackHelper()
@staticmethod
@transaction.atomic
def saveService( serviceId, serviceName, serviceNodes, machines, elementConnections ):
service = None
try:
......@@ -19,18 +20,16 @@ class SettyController:
service.name = serviceName
service.save()
#first check machine names
#validMachineNames = self.salthelper.getAllMinionsUngrouped()
Machine.objects.filter(service=service).delete()
for machineData in machines:
# if machineData["hostname"] in validMachineNames:
machineSaved = Machine(service=service)
machineSaved.fromDataDictionary( machineData )
machineSaved.save()
ServiceNode.objects.filter(service=service).delete()
for node in serviceNodes:
elementTemplateId = node["displayId"].split("_")[0]
elementTemplateId = node["displayId"].split("_")[1]
elementTemplate = ElementTemplate.objects.get(id=elementTemplateId)
newNode = get_model('setty', elementTemplate.prototype ).clone()
......@@ -43,7 +42,6 @@ class SettyController:
targetId = elementConnection['targetId']
sourceEndpoint = elementConnection['sourceEndpoint']
targetEndpoint = elementConnection['targetEndpoint']
connectionParameters = elementConnection['parameters']
targetObject = Element.objects.get(
display_id=targetId)
......@@ -55,12 +53,12 @@ class SettyController:
target=targetObject,
source=sourceObject,
target_endpoint=targetEndpoint,
source_endpoint=sourceEndpoint,
parameters=connectionParameters
source_endpoint=sourceEndpoint
)
connectionObject.save()
return {"serviceName": serviceName}
return {"serviceName": serviceName}
@staticmethod
def loadService(serviceId):
......@@ -149,9 +147,9 @@ class SettyController:
model = get_model('setty', elementTemplate.prototype )
return model.clone().getDataDictionary()
except ElementTemplate.DoesNotExist:
return {'error': 'lofaszka' }
return {'error': "ElementTemplate doesn't exists" }
except:
return {'error': 'valami nagyon el lett baszva'}
return {'error': 'Can not get prototype'}
else:
return {'error': 'templateid'}
......@@ -189,7 +187,7 @@ class SettyController:
configuratedNodes.append( generatedNodes )
#phase three: sort the nodes by deployment priority(lower the prio, later in the deployement)
configuratedNodes.sort(reverse=True)
#deploy the nodes
......@@ -199,4 +197,4 @@ class SettyController:
#cleanup the temporary data
''' for node in configuratedNodes:
node.deployCleanUp()'''
\ No newline at end of file
node.deployCleanUp()'''
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('setty', '0022_merged'),
]
operations = [
migrations.RemoveField(
model_name='elementconnection',
name='parameters',
),
]
......@@ -122,15 +122,13 @@ class ElementConnection(models.Model):
on_delete=models.CASCADE)
source_endpoint = models.TextField()
target_endpoint = models.TextField()
parameters = models.TextField()
def __unicode__(self):
return "%d" % self.id
def getDataDictionary(self):
return {'targetEndpoint': self.target_endpoint,
'sourceEndpoint': self.source_endpoint,
'parameters': self.parameters}
'sourceEndpoint': self.source_endpoint }
class Machine(Element): # As a real machine
......@@ -233,22 +231,22 @@ class WebServerNode(ServiceNode):
def getDataDictionary(self):
element_data = ServiceNode.getDataDictionary(self)
self_data = {'useSSL': self.useSSL,
'listeningPort': self.listeningPort}
self_data = {'use-ssl': self.useSSL,
'listeningport': self.listeningPort}
element_data.update(self_data)
return element_data
def fromDataDictionary(self, data):
ServiceNode.fromDataDictionary(self, data)
self.useSSL = data['useSSL']
self.listeningPort = data['listeningPort']
self.useSSL = data['use-ssl']
self.listeningPort = data['listeningport']
@staticmethod
def getInformation():
superInformation = ServiceNode.getInformation()
ownInformation = {'useSSL': WebServerNode._meta.get_field('useSSL').get_internal_type(),
'listeningPort': WebServerNode._meta.get_field('listeningPort').get_internal_type()}
ownInformation = {'use-ssl': WebServerNode._meta.get_field('useSSL').get_internal_type(),
'listeningport': WebServerNode._meta.get_field('listeningport').get_internal_type()}
ownInformation.update(superInformation)
return ownInformation
......@@ -316,7 +314,9 @@ class DatabaseNode(ServiceNode):
def getDataDictionary(self):
element_data = ServiceNode.getDataDictionary(self)
self_data = {'admin_username': self.adminUserName,
'admin_password': self.adminPassword, 'listeningPort': self.listeningPort}
'admin_password': self.adminPassword,
'listeningport': self.listeningPort }
element_data.update(self_data)
return element_data
......@@ -324,14 +324,14 @@ class DatabaseNode(ServiceNode):
ServiceNode.fromDataDictionary(self, data)
self.adminUserName = data['admin_username']
self.adminPassword = data['admin_password']
self.listeningPort = data['listeningPort']
self.listeningPort = data['listeningport']
@staticmethod
def getInformation():
superInformation = ServiceNode.getInformation()
ownInformation = {'admin_username': DatabaseNode._meta.get_field('adminUserName').get_internal_type(),
'admin_password': DatabaseNode._meta.get_field('adminPassword').get_internal_type(),
'listeningPort': DatabaseNode._meta.get_field('listeningPort').get_internal_type()}
'listeningport': DatabaseNode._meta.get_field('listeningPort').get_internal_type()}
ownInformation.update(superInformation)
return ownInformation
......
......@@ -6,11 +6,11 @@ import salt.client
SALTSTACK_STATE_FOLDER = "/srv/salt"
class SaltStackHelper:
def __init__(self):
self.master_opts = salt.config.client_config('/etc/salt/master')
self.salt_runner = salt.runner.RunnerClient(self.master_opts)
self.salt_localclient = salt.client.LocalClient()
self.salt_caller = salt.client.Caller()
# def __init__(self):
#self.master_opts = salt.config.client_config('/etc/salt/master')
#self.salt_runner = salt.runner.RunnerClient(self.master_opts)
#self.salt_localclient = salt.client.LocalClient()
#self.salt_caller = salt.client.Caller()
def getAllMinionsGrouped(self):
query_result = self.salt_runner.cmd('manage.status', []);
......
......@@ -96,99 +96,97 @@ jsPlumb.ready(function() {
addInfo = function(title, info, type, object) {
id = object.attr("id").split("_")[1];
information = undefined;
$.post("", {
event: "getInformation",
data: JSON.stringify({
"elementTemplateId": object.attr("id").split("_")[1],
"hostname": object.attr("hostname")})
"elementTemplateId": object.attr("id").split("_")[1] ,
"hostname": object.attr("hostname")} )
}, function(result) {
alert(result);
});
/*
$("#informationContainer").empty();
switch(type){
case "connection":
div =
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<h4>' + title + '</h4>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12">' +
'<textarea class="form-control" rows="28" id="infoInput" placeholder="Config data"></textarea>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<button id="removeConnection" class="btn btn-info">Remove connection</button>' +
'</div>' +
'</div>';
break;
case "element":
div =
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<h4>' + title + '</h4>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12">' +
'<textarea class="form-control" rows="24" id="infoInput" placeholder="Config data"></textarea>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row text-center">' +
'<label>Endpoints</label>' +
/*case "connection":
div =
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<h4>' + title + '</h4>' +
'</div>' +
'<div class="row">' +
'<div class="col-xs-6 text-center">' +
'<button id="addEndpoint" class="btn btn-success"><i class="fa fa-plus"></i></button>' +
'</div>' +
'<div class="col-xs-6 text-center">' +
'<button id="removeEndpoint" class="btn btn-danger"><i class="fa fa-minus"></i></button>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<button id="removeElementFromWorkspace" class="btn btn-info">Remove from workspace</button>' +
'</div>' +
'</div>';
break;
case "elementTemplate":
div =
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<h4>' + title + '</h4>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12">' +
'<textarea class="form-control" rows="28" id="infoInput" placeholder="Config data"></textarea>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<button id="addElementToWorkspace" class="btn btn-success">Add to workspace</button>' +
'</div>' +
'</div>';
break;
}*/
// Here comes the ajax getInformation post.
// elementtemplateid vagy hostname
div = 0;
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12">' +
'<textarea class="form-control" rows="28" id="infoInput" placeholder="Config data"></textarea>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<button id="removeConnection" class="btn btn-info">Remove connection</button>' +
'</div>' +
'</div>';
break;*/
case "element":
$.each( result, function(fieldName, fieldType)
{
form_group = $("<div class='form-group'></div>");
label = $("<label></label>").attr("for",fieldName).append( fieldName );
switch( fieldType )
{
//#TODO: Gaben: handle additional types
case 'PositiveIntegerField':
input = $("<input>").prop("type","number" ).prop("min",0).addClass("form-control");
value = object.attr( "data-"+ fieldName );
if( value )
input.prop("value",value );
break;
case 'TextField':
case 'CharField':
input = $("<input>").prop("type","text" ).addClass("form-control");
value = object.attr( "data-"+ fieldName );
if( value )
input.prop("value",value );
break;
case 'BooleanField':
input = $("<input>").prop("type","checkbox" );
break;
default:
alert( "unknown field type: " + fieldType );
break;
}
$("#informationContainer").append(div);
input.attr("attribute-name", "data-" + fieldName );
input.prop("id", "input-data-" + fieldName)
form_group.append( label );
form_group.append( input );
$("#informationContainer").append( form_group )
} );
break;
/*case "elementTemplate":
div =
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<h4>' + title + '</h4>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12">' +
'<textarea class="form-control" rows="28" id="infoInput" placeholder="Config data"></textarea>' +
'</div>' +
'</div>&nbsp;' +
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<button id="addElementToWorkspace" class="btn btn-success">Add to workspace</button>' +
'</div>' +
'</div>';
break;*/
}
$("#infoInput").val(info);
$("#changeInformationDialog").modal('show');
sharedObject = object;
});
};
updateConnections = function(connection, remove) {
......@@ -384,12 +382,9 @@ jsPlumb.ready(function() {
connectEndpoints = function(data) {
connectionObject =
jsPlumbInstance.connect({
source: data[0],
target: data[1]
uuids: data
});
connectionObject.parameters = data[2];
setServiceStatus("unsaved");
};
......@@ -405,6 +400,8 @@ jsPlumb.ready(function() {
};
addElement = function(idOrInstance, newId, newPositionY, endpoints, parameters, newPositionX) {
var skippedAttributes = [ 'displayId', 'positionLeft', 'positionTop','anchorNumber' ];
newInstance = "";
if (typeof idOrInstance != "string") {
......@@ -419,11 +416,16 @@ jsPlumb.ready(function() {
.removeClass()
.addClass("element")
.attr("anchors", 0)
.attr("parameters", parameters)
.css("top", newPositionY)
.css("left", newPositionX);
}
$.each(parameters, function(key, value)
{
if( skippedAttributes.indexOf( key ) == -1 )
newInstance.attr("data-"+key, value || "");
});
$("#dropContainer").append(newInstance);
for (i = 0; i <= endpoints; i++) {
......@@ -440,6 +442,7 @@ jsPlumb.ready(function() {
return newInstance;
};
addMachine = function(idOrInstance, newId, newPositionY, endpoints, parameters, newPositionX) {
newInstance = "";
......@@ -537,20 +540,39 @@ jsPlumb.ready(function() {
});
/* Registering events using JQuery. */
/* Registering general events using JQuery. */
/* Adding new element to service */
$('body').on('click', '.elementTemplate', function() {
addElement($(this).attr("id"),
(++elementIndex) + "_" + $(this).attr("id"),
(elementIndex % 21) * 30, 4, "",
var elementTemplate = $(this)
$.post("", {
event: "addServiceNode",
data: JSON.stringify({
"elementTemplateId": $(this).attr("id") })
}, function(result) {
addElement($(elementTemplate).attr("id"),
(++elementIndex) + "_" + $(elementTemplate).attr("id"),
(elementIndex % 21) * 30, 4, result,
(elementIndex % 21) * 30);
undoStack.splice(stackIndexer, 0, removeElement);
redoStack.splice(stackIndexer, 0, addElement);
objectStack.splice(stackIndexer, 0, newInstance);
stackSize++;
stackIndexer++;
undoStack.splice(stackIndexer, 0, removeElement);
redoStack.splice(stackIndexer, 0, addElement);
objectStack.splice(stackIndexer, 0, newInstance);
stackSize++;
stackIndexer++;
});
});
/* element editor dialog save*/
$('body').on('click', '#informationDialogSave', function(){
$("[id^=input-data-]").each( function( index, item ){
sharedObject.attr( $(item).attr("attribute-name"), $(item).prop( "value" ) );
} );
});
/* ---------------------------------------- */
$('body').on('dblclick', '.element', function() {
element = $(this);
......@@ -792,17 +814,23 @@ jsPlumb.ready(function() {
"sourceId": elementConnections[index].sourceId,
"sourceEndpoint": elementConnections[index].endpoints[0].getUuid(),
"targetId": elementConnections[index].targetId,
"targetEndpoint": elementConnections[index].endpoints[1].getUuid(),
"parameters": elementConnections[index].parameters});
"targetEndpoint": elementConnections[index].endpoints[1].getUuid() });
});
$.each($(".element"), function() {
instanceSet.push({
"displayId": $(this).prop("id"),
"positionLeft": $(this).position().left/workspaceWidth,
"positionTop": $(this).position().top/workspaceHeight,
"anchorNumber": $(this).attr("anchors"),
"parameters": $(this).attr("parameters")});
$.each($(".element"), function( index, item ) {
basic_data = { "anchorNumber": $(item).attr("anchors"),
"positionLeft": $(item).position().left/workspaceWidth,
"positionTop": $(item).position().top/workspaceHeight,
"displayId": $(item).prop("id") };
attributes = item.attributes
$.each( attributes, function(key,attribute){
if( attribute.name.indexOf("data-") != -1 ){
basic_data[ attribute.name.substring( attribute.name.indexOf('-') + 1 ) ] = attribute.value || "";
}
});
instanceSet.push( basic_data );
});
$.post("", {
......@@ -810,8 +838,8 @@ jsPlumb.ready(function() {
data: JSON.stringify({
"serviceName": serviceName,
"elementConnections": connectionSet,
"elements": instanceSet,
"machines": []}) //TODO: Dani: add machines here
"serviceNodes": instanceSet,
"machines": []})
}, function(result) {
addMessage(result.serviceName + gettext(" saved successfully."),"success");
setServiceStatus("saved");
......@@ -825,15 +853,11 @@ jsPlumb.ready(function() {
$.post("", {
event: "loadService"
}, function(result) {
$("#serviceName").text(result.serviceName);
$("#serviceName").text( result.serviceName );
$.each(result.serviceNodes, function(i, element) {
addElement(element.displayId.split('_')[1],
element.displayId,
(element.positionTop*workspaceHeight) + "px",
element.anchorNumber,
element.parameters,
(element.positionLeft*workspaceWidth) + "px");
addElement2( element );
if (elementIndex < element.displayId.split('_')[0])
elementIndex = element.displayId.split('_')[0];
elementIndex++;
......@@ -854,10 +878,54 @@ jsPlumb.ready(function() {
clickEvent = 1;
$.each(result.elementConnections,
function(i, connection) {
connectEndpoints([connection.sourceEndpoint, connection.targetEndpoint, connection.parameters]);
connectEndpoints([connection.sourceEndpoint, connection.targetEndpoint ]);
});
clickEvent = 0;
setServiceStatus("saved");
});
});
addElement2 = function(elementData) {
templateId = elementData.displayId.split('_')[1]
template = $(".elementTemplate").filter( "#" + templateId );
id = elementData.displayId.split('_')[0]
newInstance = $('<img id="' + elementData["displayId"] + '"/>')
.prop("title", "Right click to delete")
.removeClass()
.attr("anchors", 0)
.addClass("element")
.prop("src", template ? template.prop("src") : "");
var skippedVariables = ["anchorNumber", "displayId"]
$.each(elementData, function(key, value)
{
if (skippedVariables.indexOf(key) == -1 )
{
if (key === "positionTop")
newInstance.css("top", value * workspaceHeight);
else if(key === "positionLeft")
newInstance.css("left", value * workspaceWidth);
else
newInstance.attr("data-"+key, value);
}
});
$("#dropContainer").append(newInstance);
for (idx = 0; idx < elementData["anchorNumber"]; idx++)
addEndpoint(newInstance);
setServiceStatus("unsaved");
jsPlumbInstance.draggable(jsPlumb.getSelector(".element"), {
containment: $("#dropContainer")
});
jsPlumbInstance.repaintEverything();
return newInstance;
};
});
......@@ -3,6 +3,7 @@
{% load staticfiles %}
{% load i18n %}
{% block title-page %}Setty{% endblock %}
{% block content %}
......@@ -165,9 +166,13 @@
<button class="close" type="button" data-dismiss="modal">&times;</button>
<h4 class="modal-title"><i class="fa fa-info"></i>&nbsp;{% trans 'Information' %}</h4>
</div>
<div class="modal-body" id="informationContainer">
<div class="modal-body">
<form id="informationContainer">
</form>
</div>
<div class="modal-footer">
<div class="btn btn-success" id="informationDialogSave" data-dismiss="modal">Mentés</div>
<div class="btn btn-primary" data-dismiss="modal"/>Mégsem</div>
</div>
</div>
</div>
......@@ -189,6 +194,7 @@
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsPlumb/1.4.1/jquery.jsPlumb-1.4.1-all.js"></script>
{% endblock %}
......@@ -40,7 +40,6 @@ logger = logging.getLogger(__name__)
class DetailView(LoginRequiredMixin, TemplateView):
template_name = "setty/index.html"
salthelper = SaltStackHelper()
def get_context_data(self, **kwargs):
logger.debug('DetailView.get_context_data() called. User: %s',
......@@ -55,6 +54,19 @@ class DetailView(LoginRequiredMixin, TemplateView):
else:
raise PermissionDenied
#def get(self, request, *args, **kwargs):
# # service = Service.objects.get(id=kwargs['pk'])
# # if self.request.user != service.user or not self.request.user.is_superuser:
# # raise PermissionDenied
# # requestName = self.request.GET.get('event')
# # result = {}
# # if requestName == "elementPicture":
# # data = json.loads( self.request.GET.get('data') )
# # result = SettyController.getPictureName( data["elementTemplateId"] )
#
# return JsonResponse(result)
def post(self, request, *args, **kwargs):
service = Service.objects.get(id=kwargs['pk'])
if self.request.user != service.user or not self.request.user.is_superuser:
......@@ -63,28 +75,35 @@ class DetailView(LoginRequiredMixin, TemplateView):
result = {}
eventName = self.request.POST.get('event')
serviceId = kwargs['pk']
if eventName == 'loadService':
result = SettyController.loadService(serviceId)
elif eventName == "deploy":
result = SettyController.deploy(serviceId)
data = json.loads(self.request.POST.get('data'))
if eventName == "saveService":
result = SettyController.saveService(serviceId, data['serviceName'], data[
'serviceNodes'], data['machines'], data['elementConnections'])
elif eventName == "getMachineAvailableList":
result = SettyController.getMachineAvailableList(
serviceId, data["usedHostnames"])
elif eventName == "addServiceNode":
result = SettyController.addServiceNode(
data["elementTemplateId"])
elif eventName == "addMachine":
result = SettyController.addMachine(data["hostname"])
elif eventName == "getInformation":
result = SettyController.getInformation(
data['elementTemplateId'], data['hostname'])
else:
data = json.loads(self.request.POST.get('data'))
if eventName == "saveService":
result = SettyController.saveService(serviceId, data['serviceName'], data[
'serviceNodes'], data['machines'], data['elementConnections'])
elif eventName == "getMachineAvailableList":
result = SettyController.getMachineAvailableList(
serviceId, data["usedHostnames"])
elif eventName == "addServiceNode":
result = SettyController.addServiceNode(
data["elementTemplateId"])
elif eventName == "addMachine":
result = SettyController.addMachine(data["hostname"])
elif eventName == "getInformation":
templateId = ""
hostname = ""
if "elementTemplateId" in data.keys():
templateId = data['elementTemplateId']
if "hostname" in data.keys():
hostname = data['hostname']
result = SettyController.getInformation(
templateId, hostname )
return JsonResponse(result)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment