Commit 5e8e9dca by Sulyok Gabor

Bugfixes and reworking deployment[WIP]

parent 1f4825c9
...@@ -6,6 +6,7 @@ from django.db import transaction ...@@ -6,6 +6,7 @@ from django.db import transaction
from saltstackhelper import * from saltstackhelper import *
import os import os
from vm.models import Instance from vm.models import Instance
import logging
class SettyController: class SettyController:
salthelper = SaltStackHelper() salthelper = SaltStackHelper()
...@@ -113,7 +114,6 @@ class SettyController: ...@@ -113,7 +114,6 @@ class SettyController:
else: else:
raise PermissionDenied # TODO: something more meaningful raise PermissionDenied # TODO: something more meaningful
@staticmethod @staticmethod
def getMachineAvailableList(serviceId, usedHostnames, current_user): def getMachineAvailableList(serviceId, usedHostnames, current_user):
saltMinions = SettyController.salthelper.getAllMinionsUngrouped() saltMinions = SettyController.salthelper.getAllMinionsUngrouped()
...@@ -121,21 +121,23 @@ class SettyController: ...@@ -121,21 +121,23 @@ class SettyController:
savedHostNames = [] savedHostNames = []
for machine in savedMachines: for machine in savedMachines:
savedHostNames.append( machine.hostname ) savedHostNames.append(machine.hostname)
userInstances = Instance.objects.filter(owner=current_user) userInstances = Instance.objects.filter(
owner=current_user, destroyed_at=None)
userMachines = [] userMachines = []
for instance in userInstances: for instance in userInstances:
if instance.vm_name: if instance.vm_name:
userMachines.append(instance.vm_name) userMachines.append(instance.vm_name)
usedHostnamesByUser = set( savedHostNames + usedHostnames ) usedHostnamesByUser = set(savedHostNames + usedHostnames)
if not usedHostnamesByUser: if not usedHostnamesByUser:
return {'machinedata':userMachines}#{'machinedata': [machineName for machineName in userMachines if machineName in saltMinions] }
availableInstanceNames = list( set(userMachines) - usedHostnamesByUser ) return {'machinedata': [machineName for machineName in userMachines if machineName in saltMinions] }
return {'machinedata': availableInstanceNames}#[ machineName for machineName in availableInstanceNames if machineName in saltMinions ]}
availableInstances = list(set(userMachines) - usedHostnamesByUser)
return {'machinedata': [ machineName for machineName in availableInstances if machineName in saltMinions ]}
@staticmethod @staticmethod
def addMachine(hostname): def addMachine(hostname):
...@@ -180,49 +182,57 @@ class SettyController: ...@@ -180,49 +182,57 @@ class SettyController:
if errorMessages: if errorMessages:
return {'status': 'error', return {'status': 'error',
'errors': errorMessages } 'errors': errorMessages}
elementConnections = ElementConnection.objects.filter( elementConnections = ElementConnection.objects.filter(
Q(target__in=machines) | Q(source__in=machines)) Q(target__in=machines) | Q(source__in=machines))
firstLevelServiceNodes = []
# phase one: set the machine ptr in serviceNodes which can be accessed by # phase one: set the machine ptr in serviceNodes which can be accessed by
# connections from machines # connections from machines
logger = logging.getLogger('project.interesting.stuff')
for machine in machines: for machine in machines:
for connection in elementConnections: for connection in elementConnections:
serviceNode = None serviceNode = None
if connection.target.cast() == machine: if connection.target.cast() == machine:
serviceNode = connection.source.cast() serviceNode = connection.source.cast()
serviceNode.setMachineForDeploy(machine) serviceNode.setMachineForDeploy(machine)
elif connection.source.cast() == machine: elif connection.source.cast() == machine:
serviceNode = connection.target.cast() serviceNode = connection.target.cast()
serviceNode.setMachineForDeploy(machine) serviceNode.setMachineForDeploy(machine)
else:
raise PermissionDenied
firstLevelServiceNodes.append(serviceNode)
# phase two: let the nodes create configurations recursively # phase two: let the nodes create configurations recursively
configuratedNodes = list() configuratedNodes = list()
for serviceNode in firstLevelServiceNodes: for serviceNode in serviveNodeList:
generatedNodes = serviceNode.generateConfigurationRecursively() node = serviceNode.cast()
if isinstance(generatedNodes, list): node.generateSaltCommands()
configuratedNodes = configuratedNodes + generatedNodes configuratedNodes.append( node )
else:
configuratedNodes.append(generatedNodes)
# phase three: sort the nodes by deployment priority(lower the prio, # phase three: sort the nodes by deployment priority(lower the prio,
# later in the deployement) # later in the deployement)
configuratedNodes.sort(reverse=True) configuratedNodes.sort(reverse=True)
return {'status': 'success'}
# deploy the nodes # dbgCheck = []
# for node in configuratedNodes: # for node in configuratedNodes:
# SettyController.salthelper.deploy( # commandDict = []
# node.machine.hostname, node.generatedConfig) # for command in node.generatedCommands:
# return {'status': 'deployed'} # commandDict.append( command.__dict__ )
# dbgCheck.append({ "nodeName": my_instance.__class__.__name__,
# "commands": commandDict })
# return dbgCheck
# phase four: deploy the nodes
for node in configuratedNodes:
deployErrorMessages = SettyController.salthelper.executeCommand(
node.generatedCommands)
if errorMessages:
errorMessages.append(deployErrorMessages)
# phase five: cleanup generated commands
for serviceNode in firstLevelServiceNodes:
serviceNode.generatedCommands = None
# cleanup the temporary data if errorMessages:
''' for node in configuratedNodes: return {'status': 'error',
node.deployCleanUp()''' 'errors': errorMessages}
return {'status': 'success'}
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('setty', '0025_AddDatabases'),
]
operations = [
migrations.RemoveField(
model_name='wordpressnode',
name='databaseListeningPort',
),
migrations.AddField(
model_name='wordpressnode',
name='databaseName',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='adminEmail',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='adminPassword',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='adminUsername',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='databaseHost',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='databasePass',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='databaseUser',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='siteTitle',
field=models.TextField(default=b''),
),
migrations.AlterField(
model_name='wordpressnode',
name='siteUrl',
field=models.TextField(default=b''),
),
]
...@@ -23,13 +23,12 @@ from taggit.managers import TaggableManager ...@@ -23,13 +23,12 @@ from taggit.managers import TaggableManager
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from storage import OverwriteStorage from storage import OverwriteStorage
import os import os
import yaml
from saltstackhelper import SaltCommand
# TODO: derive from object or keep the tricky base function calling? SALTSTACK_PILLAR_FOLDER = "/srv/pillar"
# TODO: exceptions
SALTSTACK_STATE_FOLDER = "/srv/salt"
# Replacer method for configuration generation
def replaceParameter(config, parameterToReplace, newValue): def replaceParameter(config, parameterToReplace, newValue):
configEdited = config.replace(parameterToReplace, str(newValue)) configEdited = config.replace(parameterToReplace, str(newValue))
return configEdited return configEdited
...@@ -114,6 +113,9 @@ class Element(InheritanceCastModel): ...@@ -114,6 +113,9 @@ class Element(InheritanceCastModel):
self.position_top = data["positionTop"] self.position_top = data["positionTop"]
self.anchor_number = data["anchorNumber"] self.anchor_number = data["anchorNumber"]
# ElementConnection represents connection between Elements. Has a source
# and a target endpoint.
class ElementConnection(models.Model): class ElementConnection(models.Model):
target = models.ForeignKey( target = models.ForeignKey(
...@@ -134,8 +136,11 @@ class ElementConnection(models.Model): ...@@ -134,8 +136,11 @@ class ElementConnection(models.Model):
return {'targetEndpoint': self.target_endpoint, return {'targetEndpoint': self.target_endpoint,
'sourceEndpoint': self.source_endpoint} 'sourceEndpoint': self.source_endpoint}
# Represents an CIRCLE VM Instance which is known by Salt-Master and used
# in Setty configuration
class Machine(Element): # As a real machine
class Machine(Element):
MACHINE_STATUS_CHOICES = ( MACHINE_STATUS_CHOICES = (
(1, 'Running'), (1, 'Running'),
(2, 'Unreachable')) (2, 'Unreachable'))
...@@ -185,7 +190,7 @@ class ServiceNode(Element): ...@@ -185,7 +190,7 @@ class ServiceNode(Element):
default=None, upload_to='setty/node_configs/', storage=OverwriteStorage()) default=None, upload_to='setty/node_configs/', storage=OverwriteStorage())
description = models.TextField(default="") description = models.TextField(default="")
machine = None # for deploying machine = None # for deploying
generatedConfig = None generatedCommands = []
def __unicode__(self): def __unicode__(self):
return "%s" % self.name return "%s" % self.name
...@@ -224,11 +229,11 @@ class ServiceNode(Element): ...@@ -224,11 +229,11 @@ class ServiceNode(Element):
serviceNode = None serviceNode = None
if connection.target.cast() == self: if connection.target.cast() == self:
if isinstance(connection.source.cast(), ObjOther): if isinstance(connection.source.cast(), ObjOther):
return True return connection.source.cast()
elif connection.source.cast() == self: elif connection.source.cast() == self:
if isinstance(connection.target.cast(), ObjOther): if isinstance(connection.target.cast(), ObjOther):
return True return connection.target.cast()
return False return None
def __cmp__(self, other): def __cmp__(self, other):
return self.getDeploymentPriority(self).__cmp__(other.getDeploymentPriority(other)) return self.getDeploymentPriority(self).__cmp__(other.getDeploymentPriority(other))
...@@ -240,29 +245,36 @@ class ServiceNode(Element): ...@@ -240,29 +245,36 @@ class ServiceNode(Element):
def getDeploymentPriority(self): def getDeploymentPriority(self):
return 0 return 0
def generateConfigurationRecursively(self): def generateSaltCommands(self):
raise PermissionDenied
def replacePillarParameters(self, pillar):
raise PermissionDenied raise PermissionDenied
class WordpressNode(ServiceNode): class WordpressNode(ServiceNode):
# DB related fields # DB related fields
databaseListeningPort = models.PositiveIntegerField() databaseName = models.TextField(default="")
databaseHost = models.TextField() databaseHost = models.TextField(default="")
databaseUser = models.TextField() databaseUser = models.TextField(default="")
databasePass = models.TextField() databasePass = models.TextField(default="")
# admin user # admin user
adminUsername = models.TextField() adminUsername = models.TextField(default="")
adminPassword = models.TextField() adminPassword = models.TextField(default="")
adminEmail = models.TextField() adminEmail = models.TextField(default="")
# site related fields # site related fields
siteTitle = models.TextField() siteTitle = models.TextField(default="")
siteUrl = models.TextField() siteUrl = models.TextField(default="")
@staticmethod
def clone():
return WordpressNode()
def getDataDictionary(self): def getDataDictionary(self):
element_data = ServiceNode.getDataDictionary(self) element_data = ServiceNode.getDataDictionary(self)
self_data = {'database-listening-port': self.databaseListeningPort, self_data = {'database-name': self.databaseName,
'database-host': self.databaseHost, 'database-host': self.databaseHost,
'database-user': self.databaseUser, 'database-user': self.databaseUser,
'database-pass': self.databasePass, 'database-pass': self.databasePass,
...@@ -277,7 +289,7 @@ class WordpressNode(ServiceNode): ...@@ -277,7 +289,7 @@ class WordpressNode(ServiceNode):
def fromDataDictionary(self, data): def fromDataDictionary(self, data):
ServiceNode.fromDataDictionary(self, data) ServiceNode.fromDataDictionary(self, data)
self.databaseListeningPort = data['database-listening-port'] self.databaseName = data['database-name']
self.databaseHost = data['database-host'] self.databaseHost = data['database-host']
self.databaseUser = data['database-user'] self.databaseUser = data['database-user']
self.databasePass = data['database-pass'] self.databasePass = data['database-pass']
...@@ -290,10 +302,7 @@ class WordpressNode(ServiceNode): ...@@ -290,10 +302,7 @@ class WordpressNode(ServiceNode):
@staticmethod @staticmethod
def getInformation(): def getInformation():
superInformation = ServiceNode.getInformation() superInformation = ServiceNode.getInformation()
ownInformation = {'use-ssl': WebServerNode._meta.get_field('useSSL').get_internal_type(), ownInformation = {'database-name': WordpressNode._meta.get_field('databaseName').get_internal_type(),
'listeningport': WebServerNode._meta.get_field('listeningport').get_internal_type()}
ownInformation = {'database-listening-port': WordpressNode._meta.get_field('databaseListeningPort').get_internal_type(),
'database-host': WordpressNode._meta.get_field('databaseHost').get_internal_type(), 'database-host': WordpressNode._meta.get_field('databaseHost').get_internal_type(),
'database-user': WordpressNode._meta.get_field('databaseUser').get_internal_type(), 'database-user': WordpressNode._meta.get_field('databaseUser').get_internal_type(),
'database-pass': WordpressNode._meta.get_field('databasePass').get_internal_type(), 'database-pass': WordpressNode._meta.get_field('databasePass').get_internal_type(),
...@@ -309,8 +318,8 @@ class WordpressNode(ServiceNode): ...@@ -309,8 +318,8 @@ class WordpressNode(ServiceNode):
def checkDependenciesAndAttributes(self): def checkDependenciesAndAttributes(self):
errorMessages = ServiceNode.checkDependenciesAndAttributes(self) errorMessages = ServiceNode.checkDependenciesAndAttributes(self)
if self.databaseListeningPort == 0: if not self.databaseHost:
errorMessages.append("LISTENING_PORT_NOT_SET") errorMessage.append("DATABASENAME_NOT_SET")
if not self.databaseHost: if not self.databaseHost:
errorMessage.append("DATABASEHOST_NOT_SET") errorMessage.append("DATABASEHOST_NOT_SET")
if not self.databaseUser: if not self.databaseUser:
...@@ -341,9 +350,8 @@ class WordpressNode(ServiceNode): ...@@ -341,9 +350,8 @@ class WordpressNode(ServiceNode):
return 10 return 10
def generateConfiguration(self, config=""): def generateConfiguration(self, config=""):
config = replaceParameter( config = replaceParameter(
config, r'%%DATABASE_LISTENING_PORT%%', self.databaseListeningPort) config, r'%%DATABASE_NAME%%', self.databaseName)
config = replaceParameter( config = replaceParameter(
config, r'%%DATABASE_HOST%%', self.databaseHost) config, r'%%DATABASE_HOST%%', self.databaseHost)
config = replaceParameter( config = replaceParameter(
...@@ -360,6 +368,30 @@ class WordpressNode(ServiceNode): ...@@ -360,6 +368,30 @@ class WordpressNode(ServiceNode):
return config return config
def generateSaltCommands(self):
pillarFilePath = os.path.join(
SALTSTACK_PILLAR_FOLDER, "wordpress.sls")
with open(pillarFilePath, 'r') as pillar:
mysqlNode = self.checkDependecy(MySQLNode)
apacheNode = self.checkDependecy(ApacheNode)
if not mysqlNode:
raise PermissionDenied
if not apacheNode:
raise PermissionDenied
self.machine = apacheNode.machine
createMySQLUserCommand = mysqlNode.makeCreateDatabaseCommand(
self.databaseName)
createMySQLUserCommand = mysqlNode.makeCreateUserCommand(
self.databaseUser, self.databasePass)
config = str(yaml.load(pillar))
config = replacePillarParameters(pillar)
saltCommand = SaltCommand(
hostname=machine.hostname, command="wordpress", parameters=[eval(config)])
self.generatedCommands = [createMySQLUserCommand, saltCommand]
class WebServerNode(ServiceNode): class WebServerNode(ServiceNode):
useSSL = models.BooleanField(default=False) useSSL = models.BooleanField(default=False)
...@@ -393,7 +425,7 @@ class WebServerNode(ServiceNode): ...@@ -393,7 +425,7 @@ class WebServerNode(ServiceNode):
def getInformation(): def getInformation():
superInformation = ServiceNode.getInformation() superInformation = ServiceNode.getInformation()
ownInformation = {'use-ssl': WebServerNode._meta.get_field('useSSL').get_internal_type(), ownInformation = {'use-ssl': WebServerNode._meta.get_field('useSSL').get_internal_type(),
'listeningport': WebServerNode._meta.get_field('listeningport').get_internal_type()} 'listeningport': WebServerNode._meta.get_field('listeningPort').get_internal_type()}
ownInformation.update(superInformation) ownInformation.update(superInformation)
return ownInformation return ownInformation
...@@ -408,6 +440,12 @@ class WebServerNode(ServiceNode): ...@@ -408,6 +440,12 @@ class WebServerNode(ServiceNode):
r"%%LISTENING_PORT%%", self.listeningPort) r"%%LISTENING_PORT%%", self.listeningPort)
return config return config
def replacePillarParameters(self, pillar):
config = replaceParameter(config, r"%%USE_SSL%%", self.useSSL)
config = replaceParameter(config,
r"%%LISTENING_PORT%%", self.listeningPort)
return config
class ApacheNode(WebServerNode): class ApacheNode(WebServerNode):
...@@ -415,22 +453,15 @@ class ApacheNode(WebServerNode): ...@@ -415,22 +453,15 @@ class ApacheNode(WebServerNode):
def clone(): def clone():
return ApacheNode() return ApacheNode()
def generateConfigurationRecursively(self): def generateSaltCommands(self):
config = str() pillarFilePath = os.path.join(
exampleFilePath = os.path.join( SALTSTACK_PILLAR_FOLDER, "apache.sls")
SALTSTACK_STATE_FOLDER, "apache.example") with open(pillarFilePath, 'r') as pillar:
with open(exampleFilePath, 'r') as configFile: config = str(yaml.load(pillar))
config = configFile.read() config = WebServerNode.replacePillarParameters(self, pillar)
config = WebServerNode.generateConfiguration(self, config) saltCommand = SaltCommand(
hostname=machine.hostname, command="apache", parameters=eval(config))
self.generatedConfig = "apache_%s.sls" % self.machine.hostname self.generatedCommands = [saltCommand]
with open(os.path.join(SALTSTACK_STATE_FOLDER, self.generatedConfig), 'w') as generatedConfigFile:
generatedConfigFile.write(config)
configuredNodes = []
configuredNodes.append(self)
return configuredNodes
class NginxNode(WebServerNode): class NginxNode(WebServerNode):
...@@ -465,23 +496,19 @@ class NginxNode(WebServerNode): ...@@ -465,23 +496,19 @@ class NginxNode(WebServerNode):
def clone(): def clone():
return NginxNode() return NginxNode()
def generateConfigurationRecursively(self): def generateSaltCommands(self):
config = str() pillarFilePath = os.path.join(
exampleFilePath = os.path.join(SALTSTACK_STATE_FOLDER, "nginx.example") SALTSTACK_PILLAR_FOLDER, "nginx.sls")
with open(exampleFilePath, 'r') as configFile: with open(pillarFilePath, 'r') as pillar:
config = configFile.read() config = str(yaml.load(pillar))
config = WebServerNode.generateConfiguration(self, config) config = WebServerNode.replacePillarParameters(self, pillar)
config = replaceParameter(config, config = replaceParameter(config,
r"%%WORKER_CONNECTIONS%%", self.worker_connections) r"%%WORKER_CONNECTIONS%%", self.worker_connections)
self.generatedConfig = "nginx_%s.sls" % self.machine.hostname saltCommand = SaltCommand(
with open(os.path.join(SALTSTACK_STATE_FOLDER, self.generatedConfig), 'w') as generatedConfigFile: hostname=machine.hostname, command="nginx", parameters=eval(config))
generatedConfigFile.write(config)
configuredNodes = []
configuredNodes.append(self)
return configuredNodes self.generatedCommands = [saltCommand]
class DatabaseNode(ServiceNode): class DatabaseNode(ServiceNode):
...@@ -531,14 +558,14 @@ class DatabaseNode(ServiceNode): ...@@ -531,14 +558,14 @@ class DatabaseNode(ServiceNode):
def getDeploymentPriority(self): def getDeploymentPriority(self):
return 10 return 10
def generateConfiguration(self, config=""): def replacePillarParameters(self, pillar):
config = replaceParameter(config, pillar = replaceParameter(pillar,
r"%%ADMIN_USERNAME%%", self.adminUserName) r"%%ADMIN_USERNAME%%", self.adminUserName)
config = replaceParameter(config, pillar = replaceParameter(pillar,
r"%%ADMIN_PASSWORD%%", self.adminUserName) r"%%ADMIN_PASSWORD%%", self.adminUserName)
config = replaceParameter(config, pillar = replaceParameter(pillar,
r'%%LISTENING_PORT%%', self.listeningPort) r'%%LISTENING_PORT%%', self.listeningPort)
return config return pillar
class PostgreSQLNode(DatabaseNode): class PostgreSQLNode(DatabaseNode):
...@@ -547,19 +574,15 @@ class PostgreSQLNode(DatabaseNode): ...@@ -547,19 +574,15 @@ class PostgreSQLNode(DatabaseNode):
def clone(): def clone():
return PostgreSQLNode() return PostgreSQLNode()
def generateConfigurationRecursively(self): def generateSaltCommands(self):
config = str() pillarFilePath = os.path.join(
exampleFilePath = os.path.join( SALTSTACK_PILLAR_FOLDER, "nginx.sls")
SALTSTACK_STATE_FOLDER, "postgres.example") with open(pillarFilePath, 'r') as pillar:
with open(exampleFilePath, 'r') as configFile: config = str(yaml.load(pillar))
config = configFile.read() config = DatabaseNode.replacePillarParameters(self, pillar)
config = DatabaseNode.generateConfiguration(self, config) saltCommand = SaltCommand(
hostname=machine.hostname, command="postgresql", parameters=eval(config))
self.generatedConfig = "postgres_%s.sls" % self.machine.hostname self.generatedCommands = [saltCommand]
with open(os.path.join(SALTSTACK_STATE_FOLDER, self.generatedConfig), 'w') as generatedConfigFile:
generatedConfigFile.write(config)
return self
class MySQLNode(DatabaseNode): class MySQLNode(DatabaseNode):
...@@ -568,15 +591,25 @@ class MySQLNode(DatabaseNode): ...@@ -568,15 +591,25 @@ class MySQLNode(DatabaseNode):
def clone(): def clone():
return MySQLNode() return MySQLNode()
def generateConfigurationRecursively(self): def makeCreateDatabaseCommand(self, databaseName):
config = str() saltCommand = SaltCommand()
exampleFilePath = os.path.join(SALTSTACK_STATE_FOLDER, "mysql.example") saltCommand.hostname = self.machine.hostname
with open(exampleFilePath, 'r') as configFile: saltCommand.command = "mysql.database"
config = configFile.read() saltCommand.parameters = [databaseName]
config = DatabaseNode.generateConfiguration(self, config)
def makeCreateUserCommand(self, databaseUser, databasePass, availableDatabases):
self.generatedConfig = "mysql_%s.sls" % self.machine.hostname saltCommand = SaltCommand()
with open(os.path.join(SALTSTACK_STATE_FOLDER, self.generatedConfig), 'w') as generatedConfigFile: saltCommand.hostname = self.machine.hostname
generatedConfigFile.write(config) saltCommand.command = "mysql.user"
saltCommand.parameters = {databaseUser: {'password': databasePass, 'host': 'localhost', 'databases': [
return self {'database': availableDatabases, 'grants': ['all privileges']}]}}
def generateSaltCommands(self):
pillarFilePath = os.path.join(
SALTSTACK_PILLAR_FOLDER, "nginx.sls")
with open(pillarFilePath, 'r') as pillar:
config = str(yaml.load(pillar))
config = DatabaseNode.replacePillarParameters(self, pillar)
saltCommand = SaltCommand(
hostname=machine.hostname, command="mysql.server", parameters=eval(config))
self.generatedCommands = [saltCommand]
\ No newline at end of file
...@@ -3,8 +3,16 @@ import salt.config ...@@ -3,8 +3,16 @@ import salt.config
import salt.runner import salt.runner
import salt.client import salt.client
class SaltCommand:
def __init__(self):
self.hostname = ""
self.command = ""
self.parameters = ""
# For debugging purposes only
def __str__(self):
return "Command: " + self.hostname + " - " + self.command + " - " + str(self.parameters)
SALTSTACK_STATE_FOLDER = "/srv/salt"
class SaltStackHelper: class SaltStackHelper:
def __init__(self): def __init__(self):
self.master_opts = salt.config.client_config('/etc/salt/master') self.master_opts = salt.config.client_config('/etc/salt/master')
...@@ -38,9 +46,7 @@ class SaltStackHelper: ...@@ -38,9 +46,7 @@ class SaltStackHelper:
def checkMinionExists(self, hostname): def checkMinionExists(self, hostname):
query_res = self.salt_localclient.cmd( hostname,'network.get_hostname' ); query_res = self.salt_localclient.cmd( hostname,'network.get_hostname' );
print query_res
return query_res != {} return query_res != {}
def deploy(self, hostname, configFilePath ): def executeCommand(self, saltCommand):
print configFilePath return self.salt_localclient.cmd(saltCommand.hostname, "state.sls",[saltCommand.command],kwarg={"pillar":saltCommand.parameters} )
self.salt_localclient.cmd(hostname, 'state.apply', [configFilePath.split('.')[0]] )
\ No newline at end of file
...@@ -501,7 +501,7 @@ jsPlumb.ready(function() { ...@@ -501,7 +501,7 @@ jsPlumb.ready(function() {
$.post("", { $.post("", {
event: "addServiceNode", event: "addServiceNode",
data: JSON.stringify({ data: JSON.stringify({
"elementTemplateId": $(this).attr("id") }) "elementTemplateId": $(elementTemplate).attr("id") })
}, function(result) { }, function(result) {
addElement($(elementTemplate).attr("id"), addElement($(elementTemplate).attr("id"),
(++elementIndex) + "_" + $(elementTemplate).attr("id"), (++elementIndex) + "_" + $(elementTemplate).attr("id"),
...@@ -791,10 +791,15 @@ jsPlumb.ready(function() { ...@@ -791,10 +791,15 @@ jsPlumb.ready(function() {
/* Registering events concerning persistence. */ /* Registering events concerning persistence. */
$('body').on('click', '#deployService',function() { $('body').on('click', '#deployService',function() {
if($("#serviceStatus").text() == "Unsaved") {
alert("Only saved services can be deployed");
return;
}
$.post("", { $.post("", {
event: "deploy", event: "deploy",
}, function(result) { }, function(result) {
if ( result.error ) if ( result.status )
alert( result.errors ); alert( result.errors );
else else
alert("Deploying...."); alert("Deploying....");
......
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