Commit e13d6e98 by Sulyok Gabor

Better error messages and bugfixes, some code cleanup

parent 67dd3488
...@@ -131,6 +131,8 @@ class SettyController: ...@@ -131,6 +131,8 @@ class SettyController:
@staticmethod @staticmethod
def getInformation(elementTemplateId, hostname): def getInformation(elementTemplateId, hostname):
if hostname and elementTemplateId:
return {'status': 'error', 'errors': 'BOTH_ELEMENTEMPLATE_HOSTNAME_FILLED'}
if elementTemplateId: if elementTemplateId:
try: try:
elementTemplate = ElementTemplate.objects.get( elementTemplate = ElementTemplate.objects.get(
...@@ -143,8 +145,6 @@ class SettyController: ...@@ -143,8 +145,6 @@ class SettyController:
return {'status': 'error', 'errors': 'ELEMENTTEMPLATE_COULDNT_GET_PROTOTYPE'} return {'status': 'error', 'errors': 'ELEMENTTEMPLATE_COULDNT_GET_PROTOTYPE'}
elif hostname: elif hostname:
return Machine.getInformation() return Machine.getInformation()
elif hostname and elementTemplateId:
return {'status': 'error', 'errors': 'BOTH_ELEMENTEMPLATE_HOSTNAME_FILLED'}
else: else:
return {'status': 'error', 'errors': 'UNKNOWN_ERROR'} return {'status': 'error', 'errors': 'UNKNOWN_ERROR'}
...@@ -155,13 +155,7 @@ class SettyController: ...@@ -155,13 +155,7 @@ class SettyController:
''' '''
@staticmethod @staticmethod
def getMachineAvailableList(serviceId, usedHostnames, current_user): def getMachineAvailableList( usedHostnames, current_user):
savedMachines = Machine.objects.filter(service=serviceId)
savedHostNames = []
for machine in savedMachines:
savedHostNames.append(machine.hostname)
userInstances = Instance.objects.filter( userInstances = Instance.objects.filter(
owner=current_user, destroyed_at=None) owner=current_user, destroyed_at=None)
userMachines = [] userMachines = []
...@@ -169,14 +163,17 @@ class SettyController: ...@@ -169,14 +163,17 @@ class SettyController:
if instance.vm_name: if instance.vm_name:
userMachines.append(instance.vm_name) userMachines.append(instance.vm_name)
usedHostnamesByUser = set(savedHostNames + usedHostnames)
availableInstances = set(set(userMachines) - usedHostnamesByUser)
saltMinions = SettyController.salthelper.getAllMinionsUngrouped() saltMinions = SettyController.salthelper.getAllMinionsUngrouped()
if not usedHostnamesByUser: if not usedHostnames:
return {'machinedata': [machineName for machineName in userMachines if machineName in saltMinions]} return {'machinedata': [machineName for machineName
in userMachines if machineName in saltMinions]}
availableInstances = set(set(userMachines) - usedHostnames)
return {'machinedata':
[machineName for machineName
in availableInstances if machineName in saltMinions]}
return {'machinedata': [machineName for machineName in availableInstances if machineName in saltMinions]}
''' '''
Add a machine with the given hostname to the Service. If there is a Add a machine with the given hostname to the Service. If there is a
...@@ -185,13 +182,8 @@ class SettyController: ...@@ -185,13 +182,8 @@ class SettyController:
back the new Machine instance back the new Machine instance
''' '''
#TODO: addMachine requires usedHostnames too for safety
@staticmethod @staticmethod
def addMachine(hostname): def addMachine(hostname):
try:
Machine.objects.get(hostname=hostname)
except:
return {'status': 'error', 'errors': 'MACHINE_ALREADY_ADDED'}
if SettyController.salthelper.checkMinionExists(hostname): if SettyController.salthelper.checkMinionExists(hostname):
machine = Machine.clone() machine = Machine.clone()
machine.hostname = hostname machine.hostname = hostname
...@@ -251,19 +243,6 @@ class SettyController: ...@@ -251,19 +243,6 @@ class SettyController:
nodesToBeDeployed.sort(reverse=True) nodesToBeDeployed.sort(reverse=True)
dbgCheck = []
# for node in nodesToBeDeployed:
# commandArray = []
#
# for command in node.generatedCommands:
# logger.error( "salt '"+ command.hostname +"' state.sls " + command.command + " pillar=\"" + str(command.parameters) + '"' )
# commandArray.append( command.toDict() )
#
# dbgCheck.append({ "nodeName": str(node.__class__.__name__),
# "hostingMachineName": str(node.getHostingMachine().hostname ),
# "commands": commandArray })
#return {"status": "error", "errors":dbgCheck}
# phase three: deploy the nodes # phase three: deploy the nodes
for node in nodesToBeDeployed: for node in nodesToBeDeployed:
......
...@@ -19,6 +19,7 @@ from django.db import models ...@@ -19,6 +19,7 @@ from django.db import models
from django.db.models import Q from django.db.models import Q
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import ugettext
from storage import OverwriteStorage from storage import OverwriteStorage
import os import os
import yaml import yaml
...@@ -30,11 +31,20 @@ SALTSTACK_PILLAR_FOLDER = "/srv/pillar" ...@@ -30,11 +31,20 @@ SALTSTACK_PILLAR_FOLDER = "/srv/pillar"
salthelper = SaltStackHelper() salthelper = SaltStackHelper()
def replaceParameter(pillar, parameterToReplace, newValue): def replaceParameter(pillar, parameterToReplace, newValue):
pillarEdited = pillar.replace(parameterToReplace, str(newValue)) pillarEdited = pillar.replace(parameterToReplace, str(newValue))
return pillarEdited return pillarEdited
def createErrorMessage(errorMessage, nodeType, nodeName):
message = nodeType
if(nodeName):
message = message + "(" + nodeName + ")"
message = message + ": " + errorMessage
return message
class Service(models.Model): class Service(models.Model):
SERVICE_STATUS_CHOICES = ((1, 'Draft'), SERVICE_STATUS_CHOICES = ((1, 'Draft'),
(2, 'Deployed')) (2, 'Deployed'))
...@@ -214,7 +224,6 @@ class ServiceNode(Element): ...@@ -214,7 +224,6 @@ class ServiceNode(Element):
# The Service which the ServiceNode belongs to # The Service which the ServiceNode belongs to
service = models.ForeignKey( service = models.ForeignKey(
Service, on_delete=models.CASCADE, default=None) Service, on_delete=models.CASCADE, default=None)
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
# User's description for the ServiceNode # User's description for the ServiceNode
description = models.TextField(default="") description = models.TextField(default="")
...@@ -309,6 +318,7 @@ class ServiceNode(Element): ...@@ -309,6 +318,7 @@ class ServiceNode(Element):
def generateSaltCommands(self): def generateSaltCommands(self):
raise PermissionDenied raise PermissionDenied
class WordpressNode(ServiceNode): class WordpressNode(ServiceNode):
# DB related fields # DB related fields
databaseName = models.TextField(default="") databaseName = models.TextField(default="")
...@@ -359,7 +369,6 @@ class WordpressNode(ServiceNode): ...@@ -359,7 +369,6 @@ class WordpressNode(ServiceNode):
ownInformation = {'database-name': ownInformation = {'database-name':
WordpressNode._meta.get_field( WordpressNode._meta.get_field(
'databaseName').get_internal_type(), 'databaseName').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(),
'admin-username': WordpressNode._meta.get_field('adminUsername').get_internal_type(), 'admin-username': WordpressNode._meta.get_field('adminUsername').get_internal_type(),
...@@ -375,27 +384,37 @@ class WordpressNode(ServiceNode): ...@@ -375,27 +384,37 @@ class WordpressNode(ServiceNode):
errorMessages = ServiceNode.checkDependenciesAndAttributes(self) errorMessages = ServiceNode.checkDependenciesAndAttributes(self)
if not self.databaseName: if not self.databaseName:
errorMessages.append("DATABASENAME_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Database name is not set"), "WordPress", self.name))
if not self.databaseUser: if not self.databaseUser:
errorMessages.append("DATABASEUSER_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Database username is not set"), "WordPress", self.name))
if not self.databasePass: if not self.databasePass:
errorMessages.append("DATABASEPASS_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Database password is not set"), "WordPress", self.name))
if not self.adminUsername: if not self.adminUsername:
errorMessages.append("ADMINUSERNAME_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Administrator's username is not set"), "WordPress", self.name))
if not self.adminPassword: if not self.adminPassword:
errorMessages.append("ADMINPASSWORD_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Administrator's password is not set"), "WordPress", self.name))
if not self.adminEmail: if not self.adminEmail:
errorMessages.append("ADMINEMAIL_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Administrator's email is not set"), "WordPress", self.name))
if not self.siteTitle: if not self.siteTitle:
errorMessages.append("SITETITLE_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Site's title is not set"), "WordPress", self.name))
if not self.siteUrl: if not self.siteUrl:
errorMessages.append("SITEURL_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("Site's url is not set"), "WordPress", self.name))
if not self.checkDependecy(MySQLNode): if not self.checkDependecy(MySQLNode):
errorMessages.append("MYSQL_NOT_CONNECTED") errorMessages.append(createErrorMessage(
ugettext("No MySQL server connected to service"), "WordPress", self.name))
if not self.checkDependecy(ApacheNode): if not self.checkDependecy(ApacheNode):
errorMessages.append("WEBSERVER_NOT_CONNECTED") errorMessages.append(createErrorMessage(
ugettext("No Apache webserver connected to service"), "WordPress", self.name))
return errorMessages return errorMessages
...@@ -435,23 +454,23 @@ class WordpressNode(ServiceNode): ...@@ -435,23 +454,23 @@ class WordpressNode(ServiceNode):
installWordpressCommand.hostname = self.getHostingMachine().hostname installWordpressCommand.hostname = self.getHostingMachine().hostname
installWordpressCommand.command = "wordpress" installWordpressCommand.command = "wordpress"
installWordpressCommand.parameters = {'wordpress': installWordpressCommand.parameters = {'wordpress':
{'cli': {'cli':
{'source': {'source':
'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar', 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar',
'hash': 'hash':
'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.sha512'}, 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.sha512'},
'lookup': {'docroot': '/var/www/html'}, 'lookup': {'docroot': '/var/www/html'},
'sites': 'sites':
{'mysitename.com': {'mysitename.com':
{'username': self.adminUsername, {'username': self.adminUsername,
'password': self.adminPassword, 'password': self.adminPassword,
'database': self.databaseName, 'database': self.databaseName,
'dbhost': salthelper.getIpAddressOfMinion( mysqlNode.getHostingMachine().hostname ), 'dbhost': salthelper.getIpAddressOfMinion(mysqlNode.getHostingMachine().hostname),
'dbuser': self.databaseUser, 'dbuser': self.databaseUser,
'dbpass': self.databasePass, 'dbpass': self.databasePass,
'url': self.siteUrl, 'url': self.siteUrl,
'title': self.siteTitle, 'title': self.siteTitle,
'email': self.adminEmail}}}} 'email': self.adminEmail}}}}
installMySqlClientCommand = SaltCommand() installMySqlClientCommand = SaltCommand()
installMySqlClientCommand.hostname = self.getHostingMachine().hostname installMySqlClientCommand.hostname = self.getHostingMachine().hostname
...@@ -473,9 +492,9 @@ class WebServerNode(ServiceNode): ...@@ -473,9 +492,9 @@ class WebServerNode(ServiceNode):
def checkDependenciesAndAttributes(self): def checkDependenciesAndAttributes(self):
errorMessages = ServiceNode.checkDependenciesAndAttributes(self) errorMessages = ServiceNode.checkDependenciesAndAttributes(self)
if not self.checkDependecy(Machine): if not self.checkDependecy(Machine):
errorMessages.append("NO_MACHINE_CONNECTED") errorMessages.append(createErrorMessage(ugettext("Machine is not connected"), "WebServer", self.name))
return errorMessages return errorMessages
...@@ -538,19 +557,22 @@ class DatabaseNode(ServiceNode): ...@@ -538,19 +557,22 @@ class DatabaseNode(ServiceNode):
def checkDependenciesAndAttributes(self): def checkDependenciesAndAttributes(self):
errorMessages = ServiceNode.checkDependenciesAndAttributes(self) errorMessages = ServiceNode.checkDependenciesAndAttributes(self)
if not self.adminPassword: if not self.adminPassword:
errorMessages.append("ADMIN_PASSWORD_NAME_NOT_SET") errorMessages.append(createErrorMessage(
ugettext("No admin password set"), "Database", self.name))
if not self.checkDependecy(Machine): if not self.checkDependecy(Machine):
errorMessages.append("NO_MACHINE_CONNECTED") errorMessages.append(createErrorMessage(
ugettext("No machine connected"), "Database", self.name))
return errorMessages return errorMessages
@staticmethod @staticmethod
def getInformation(): def getInformation():
superInformation = ServiceNode.getInformation() superInformation = ServiceNode.getInformation()
ownInformation = {'admin_password': DatabaseNode._meta.get_field('adminPassword').get_internal_type()} ownInformation = {'admin_password': DatabaseNode._meta.get_field(
'adminPassword').get_internal_type()}
ownInformation.update(superInformation) ownInformation.update(superInformation)
return ownInformation return ownInformation
...@@ -558,6 +580,7 @@ class DatabaseNode(ServiceNode): ...@@ -558,6 +580,7 @@ class DatabaseNode(ServiceNode):
def getDeploymentPriority(self): def getDeploymentPriority(self):
return 10 return 10
class PostgreSQLNode(DatabaseNode): class PostgreSQLNode(DatabaseNode):
@staticmethod @staticmethod
...@@ -588,18 +611,18 @@ class MySQLNode(DatabaseNode): ...@@ -588,18 +611,18 @@ class MySQLNode(DatabaseNode):
return saltCommand return saltCommand
# Generate SaltCommand for user creation on the current MySQL instance # Generate SaltCommand for user creation on the current MySQL instance
def makeCreateUserCommand(self, databaseUser, databasePass, availableDatabases): def makeCreateUserCommand(self, databaseUser, databasePass, grantPrivilageDatabase):
saltCommand = SaltCommand() saltCommand = SaltCommand()
saltCommand.hostname = self.getHostingMachine().hostname saltCommand.hostname = self.getHostingMachine().hostname
saltCommand.command = "mysql.user" saltCommand.command = "mysql.user"
databaseGrants = [{'database': '*', 'grants': ['all privileges']}] databaseGrants = [{'database': '*', 'grants': ['all privileges']}]
if isinstance(availableDatabases, list): if isinstance(grantPrivilageDatabase, list):
for dbAccess in availableDatabases: for dbAccess in grantPrivilageDatabase:
databaseGrants.append( databaseGrants.append(
{'database': dbAccess, 'grants': ['all privileges']}) {'database': dbAccess, 'grants': ['all privileges']})
else: else:
databaseGrants.append( databaseGrants.append(
{'database': availableDatabases, 'grants': ['all privileges']}) {'database': grantPrivilageDatabase, 'grants': ['all privileges']})
saltCommand.parameters = {'mysql': { saltCommand.parameters = {'mysql': {
'server': { 'server': {
...@@ -618,6 +641,6 @@ class MySQLNode(DatabaseNode): ...@@ -618,6 +641,6 @@ class MySQLNode(DatabaseNode):
saltCommand.hostname = self.getHostingMachine().hostname saltCommand.hostname = self.getHostingMachine().hostname
saltCommand.command = "mysql.server" saltCommand.command = "mysql.server"
saltCommand.parameters = { saltCommand.parameters = {
'mysql': {'server': {'root_password': self.adminPassword, 'mysqld':{'bind-address' : '0.0.0.0'}}}} 'mysql': {'server': {'root_password': self.adminPassword, 'mysqld': {'bind-address': '0.0.0.0'}}}}
self.generatedCommands.append(saltCommand) self.generatedCommands.append(saltCommand)
...@@ -31,13 +31,6 @@ class SaltCommand: ...@@ -31,13 +31,6 @@ class SaltCommand:
self.command = "" self.command = ""
self.parameters = None self.parameters = None
# For debugging purposes only
def toDict(self):
return {'hostname': self.hostname,
'command': self.command,
'parameters': self.parameters}
class SaltStackHelper: class SaltStackHelper:
def __init__(self): def __init__(self):
......
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