Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gyuricska Milán
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5e8e9dca
authored
Oct 24, 2016
by
Sulyok Gabor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bugfixes and reworking deployment[WIP]
parent
1f4825c9
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
242 additions
and
125 deletions
+242
-125
circle/setty/controller.py
+37
-27
circle/setty/migrations/0026_WordPressMemberChange.py
+63
-0
circle/setty/models.py
+124
-90
circle/setty/saltstackhelper.py
+11
-6
circle/setty/static/setty/setty.js
+7
-2
No files found.
circle/setty/controller.py
View file @
5e8e9dca
...
@@ -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'
}
circle/setty/migrations/0026_WordPressMemberChange.py
0 → 100644
View file @
5e8e9dca
# -*- 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
''
),
),
]
circle/setty/models.py
View file @
5e8e9dca
...
@@ -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
generatedCo
nfig
=
None
generatedCo
mmands
=
[]
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
Fals
e
return
Non
e
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
database
ListeningPort
=
models
.
PositiveIntegerField
(
)
database
Name
=
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
.
database
ListeningPort
=
data
[
'database-listening-port
'
]
self
.
database
Name
=
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
:
errorMessage
s
.
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
(
'listening
p
ort'
)
.
get_internal_type
()}
'listeningport'
:
WebServerNode
.
_meta
.
get_field
(
'listening
P
ort'
)
.
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
generate
ConfigurationRecursively
(
self
):
def
generate
SaltCommands
(
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
circle/setty/saltstackhelper.py
View file @
5e8e9dca
...
@@ -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
circle/setty/static/setty/setty.js
View file @
5e8e9dca
...
@@ -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...."
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment