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
9ab17d5f
authored
Sep 20, 2016
by
Sulyok Gábor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit previous changes for Setty
parent
39a7ffc9
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1102 additions
and
219 deletions
+1102
-219
circle/setty/admin.py
+11
-3
circle/setty/controller.py
+203
-0
circle/setty/migrations/0013_saltstack_changes.py
+76
-0
circle/setty/migrations/0014_auto_20160320_1724.py
+35
-0
circle/setty/migrations/0015_allow_blank_elementcategory_parent.py
+19
-0
circle/setty/migrations/0016_auto_20160320_1753.py
+30
-0
circle/setty/migrations/0017_auto_20160320_1828.py
+30
-0
circle/setty/migrations/0018_auto_20160420_1728.py
+23
-0
circle/setty/migrations/0019_auto_20160420_2043.py
+19
-0
circle/setty/migrations/0020_auto_20160420_2132.py
+19
-0
circle/setty/migrations/0021_element_real_type.py
+20
-0
circle/setty/models.py
+329
-13
circle/setty/saltstackhelper.py
+47
-0
circle/setty/static/setty/apache.jpg
+0
-0
circle/setty/static/setty/lighttpd.jpg
+0
-0
circle/setty/static/setty/nginx.jpg
+0
-0
circle/setty/static/setty/setty.js
+203
-121
circle/setty/static/setty/ubuntu.jpg
+0
-0
circle/setty/static/setty/wordpress.jpg
+0
-0
circle/setty/tables.py
+0
-0
circle/setty/views.py
+38
-82
No files found.
circle/setty/admin.py
View file @
9ab17d5f
...
@@ -17,13 +17,21 @@
...
@@ -17,13 +17,21 @@
from
django.contrib
import
admin
from
django.contrib
import
admin
from
.models
import
(
from
.models
import
(
Element
,
Service
,
ElementCategory
,
ElementTemplate
,
ElementTemplate
,
ElementConnection
,
ElementConnection
,
Service
,
Machine
,
NginxNode
,
MySQLNode
,
PostgreSQLNode
)
)
admin
.
site
.
register
(
Element
)
admin
.
site
.
register
(
Element
Category
)
admin
.
site
.
register
(
ElementTemplate
)
admin
.
site
.
register
(
ElementTemplate
)
admin
.
site
.
register
(
ElementConnection
)
admin
.
site
.
register
(
ElementConnection
)
admin
.
site
.
register
(
Service
)
admin
.
site
.
register
(
Service
)
admin
.
site
.
register
(
Machine
)
admin
.
site
.
register
(
NginxNode
)
admin
.
site
.
register
(
MySQLNode
)
admin
.
site
.
register
(
PostgreSQLNode
)
circle/setty/controller.py
0 → 100644
View file @
9ab17d5f
from
.models
import
*
from
django.core.exceptions
import
PermissionDenied
from
django.db.models
import
Q
from
django.db.models.loading
import
get_model
from
saltstackhelper
import
*
import
os
class
SettyController
:
salthelper
=
SaltStackHelper
()
@staticmethod
def
saveService
(
serviceId
,
serviceName
,
serviceNodes
,
machines
,
elementConnections
):
service
=
None
try
:
service
=
Service
.
objects
.
get
(
id
=
serviceId
)
except
Service
.
DoesNotExist
:
return
JsonResponse
(
{
'error'
:
'Service not found'
})
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
]
elementTemplate
=
ElementTemplate
.
objects
.
get
(
id
=
elementTemplateId
)
newNode
=
get_model
(
'setty'
,
elementTemplate
.
prototype
)
.
clone
()
newNode
.
service
=
service
newNode
.
fromDataDictionary
(
node
)
newNode
.
save
()
for
elementConnection
in
elementConnections
:
sourceId
=
elementConnection
[
'sourceId'
]
targetId
=
elementConnection
[
'targetId'
]
sourceEndpoint
=
elementConnection
[
'sourceEndpoint'
]
targetEndpoint
=
elementConnection
[
'targetEndpoint'
]
connectionParameters
=
elementConnection
[
'parameters'
]
targetObject
=
Element
.
objects
.
get
(
display_id
=
targetId
)
sourceObject
=
Element
.
objects
.
get
(
display_id
=
sourceId
)
connectionObject
=
ElementConnection
(
target
=
targetObject
,
source
=
sourceObject
,
target_endpoint
=
targetEndpoint
,
source_endpoint
=
sourceEndpoint
,
parameters
=
connectionParameters
)
connectionObject
.
save
()
return
{
"serviceName"
:
serviceName
}
@staticmethod
def
loadService
(
serviceId
):
service
=
None
try
:
service
=
Service
.
objects
.
get
(
id
=
serviceId
)
except
Service
.
DoesNotExist
:
return
JsonResponse
({
'error'
:
'Service not found'
})
machineList
=
Machine
.
objects
.
filter
(
service
=
service
)
serviceNodes
=
[]
elementConnections
=
[]
machines
=
[]
for
machine
in
machineList
:
machines
.
append
(
machine
.
getDataDictionary
())
serviveNodeList
=
ServiceNode
.
objects
.
filter
(
service
=
service
)
elementConnectionList
=
ElementConnection
.
objects
.
filter
(
Q
(
target__in
=
serviveNodeList
)
|
Q
(
source__in
=
serviveNodeList
))
for
servideNode
in
serviveNodeList
:
serviceNodes
.
append
(
servideNode
.
cast
()
.
getDataDictionary
()
)
for
elementConnection
in
elementConnectionList
:
elementConnections
.
append
(
elementConnection
.
getDataDictionary
()
)
return
{
'serviceName'
:
service
.
name
,
'elementConnections'
:
elementConnections
,
'serviceNodes'
:
serviceNodes
,
'machines'
:
machines
}
@staticmethod
def
getInformation
(
elementTemplateId
,
hostname
):
if
elementTemplateId
:
try
:
elementTemplate
=
ElementTemplate
.
objects
.
get
(
id
=
elementTemplateId
)
model
=
get_model
(
'setty'
,
elementTemplate
.
prototype
)
return
model
.
getInformation
()
except
ElementTemplate
.
DoesNotExist
:
return
except
LookupError
:
return
elif
hostname
:
return
Machine
.
getInformation
()
elif
hostname
and
elementTemplateId
:
raise
PermissionDenied
# TODO: something more meaningful
else
:
raise
PermissionDenied
# TODO: something more meaningful
@staticmethod
def
getMachineAvailableList
(
service_id
,
used_hostnames
):
all_minions
=
SettyController
.
salthelper
.
getAllMinionsGrouped
()
result
=
[]
#TODO: filter out used ones
for
item
in
all_minions
[
"up"
]:
result
.
append
(
{
'hostname'
:
item
,
'hardware-info'
:
SettyController
.
salthelper
.
getMinionBasicHardwareInfo
(
item
),
'status'
:
'up'
}
)
for
item
in
all_minions
[
"down"
]:
result
.
append
(
{
'hostname'
:
item
,
'status'
:
'down'
})
return
{
'machinedata'
:
result
}
@staticmethod
def
addMachine
(
hostname
):
try
:
Machine
.
objects
.
get
(
hostname
=
hostname
)
return
{
'error'
:
'already added or doesnt exists'
}
except
:
pass
if
SettyController
.
salthelper
.
checkMinionExists
(
hostname
):
machine
=
Machine
.
clone
()
machine
.
hostname
=
hostname
return
machine
.
getDataDictionary
()
else
:
return
{
'error'
:
'already added or doesnt exists'
}
@staticmethod
def
addServiceNode
(
elementTemplateId
):
if
elementTemplateId
:
try
:
elementTemplate
=
ElementTemplate
.
objects
.
get
(
id
=
elementTemplateId
)
model
=
get_model
(
'setty'
,
elementTemplate
.
prototype
)
return
model
.
clone
()
.
getDataDictionary
()
except
ElementTemplate
.
DoesNotExist
:
return
{
'error'
:
'lofaszka'
}
except
:
return
{
'error'
:
'valami nagyon el lett baszva'
}
else
:
return
{
'error'
:
'templateid'
}
@staticmethod
def
deploy
(
serviceId
):
service
=
Service
.
objects
.
get
(
id
=
serviceId
)
machines
=
Machine
.
objects
.
filter
(
service
=
service
)
elementConnections
=
ElementConnection
.
objects
.
filter
(
Q
(
target__in
=
machines
)
|
Q
(
source__in
=
machines
)
)
firstLevelServiceNodes
=
[]
#phase one: set the machine ptr in serviceNodes which can be accessed by
# connections from machines
for
machine
in
machines
:
for
connection
in
elementConnections
:
serviceNode
=
None
if
connection
.
target
.
cast
()
==
machine
:
serviceNode
=
connection
.
source
.
cast
()
serviceNode
.
setMachineForDeploy
(
machine
)
elif
connection
.
source
.
cast
()
==
machine
:
serviceNode
=
connection
.
target
.
cast
()
serviceNode
.
setMachineForDeploy
(
machine
)
else
:
raise
PermissionDenied
firstLevelServiceNodes
.
append
(
serviceNode
)
#phase two: let the nodes create configurations recursively
configuratedNodes
=
list
()
for
serviceNode
in
firstLevelServiceNodes
:
generatedNodes
=
serviceNode
.
generateConfigurationRecursively
()
if
isinstance
(
generatedNodes
,
list
):
configuratedNodes
=
configuratedNodes
+
generatedNodes
else
:
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
for
node
in
configuratedNodes
:
SettyController
.
salthelper
.
deploy
(
node
.
machine
.
hostname
,
node
.
generatedConfig
)
return
{
'status'
:
'deployed'
}
#cleanup the temporary data
''' for node in configuratedNodes:
node.deployCleanUp()'''
\ No newline at end of file
circle/setty/migrations/0013_saltstack_changes.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
import
setty.storage
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0012_auto_20160308_1432'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'ElementCategory'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
verbose_name
=
'ID'
,
serialize
=
False
,
auto_created
=
True
,
primary_key
=
True
)),
(
'name'
,
models
.
CharField
(
max_length
=
50
)),
(
'parent_category'
,
models
.
ForeignKey
(
to
=
'setty.ElementCategory'
,
null
=
True
)),
],
),
migrations
.
CreateModel
(
name
=
'Machine'
,
fields
=
[
(
'element_ptr'
,
models
.
OneToOneField
(
parent_link
=
True
,
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
to
=
'setty.Element'
)),
(
'hostname'
,
models
.
TextField
()),
(
'alias'
,
models
.
CharField
(
max_length
=
50
)),
(
'config_file'
,
models
.
FileField
(
default
=
None
,
storage
=
setty
.
storage
.
OverwriteStorage
(),
upload_to
=
b
'setty/machine_configs/'
)),
(
'description'
,
models
.
TextField
(
default
=
b
''
)),
(
'status'
,
models
.
CharField
(
max_length
=
1
,
choices
=
[(
1
,
b
'Running'
),
(
2
,
b
'Unreachable'
)])),
],
options
=
{
'abstract'
:
False
,
},
bases
=
(
'setty.element'
,),
),
migrations
.
CreateModel
(
name
=
'ServiceNode'
,
fields
=
[
(
'element_ptr'
,
models
.
OneToOneField
(
parent_link
=
True
,
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
to
=
'setty.Element'
)),
(
'name'
,
models
.
CharField
(
max_length
=
50
)),
(
'config_file'
,
models
.
FileField
(
default
=
None
,
storage
=
setty
.
storage
.
OverwriteStorage
(),
upload_to
=
b
'setty/node_configs/'
)),
(
'description'
,
models
.
TextField
(
default
=
b
''
)),
(
'machine'
,
models
.
ForeignKey
(
to
=
'setty.Machine'
)),
],
bases
=
(
'setty.element'
,),
),
migrations
.
RemoveField
(
model_name
=
'element'
,
name
=
'parameters'
,
),
migrations
.
RemoveField
(
model_name
=
'element'
,
name
=
'service'
,
),
migrations
.
RemoveField
(
model_name
=
'elementtemplate'
,
name
=
'parameters'
,
),
migrations
.
AlterField
(
model_name
=
'service'
,
name
=
'status'
,
field
=
models
.
CharField
(
default
=
1
,
max_length
=
1
,
choices
=
[(
1
,
b
'Draft'
),
(
2
,
b
'Deployed'
)]),
),
migrations
.
AddField
(
model_name
=
'machine'
,
name
=
'service'
,
field
=
models
.
ForeignKey
(
related_name
=
'service_id'
,
to
=
'setty.Service'
),
),
migrations
.
AddField
(
model_name
=
'elementtemplate'
,
name
=
'category'
,
field
=
models
.
ForeignKey
(
to
=
'setty.ElementCategory'
,
null
=
True
),
),
]
circle/setty/migrations/0014_auto_20160320_1724.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0013_saltstack_changes'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'NginxNode'
,
fields
=
[
(
'servicenode_ptr'
,
models
.
OneToOneField
(
parent_link
=
True
,
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
to
=
'setty.ServiceNode'
)),
(
'worker_connections'
,
models
.
PositiveIntegerField
()),
],
bases
=
(
'setty.servicenode'
,),
),
migrations
.
CreateModel
(
name
=
'WebServerNode'
,
fields
=
[
(
'servicenode_ptr'
,
models
.
OneToOneField
(
parent_link
=
True
,
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
to
=
'setty.ServiceNode'
)),
(
'useSSL'
,
models
.
BooleanField
(
default
=
False
)),
(
'listeningPort'
,
models
.
PositiveIntegerField
()),
],
bases
=
(
'setty.servicenode'
,),
),
migrations
.
RemoveField
(
model_name
=
'elementtemplate'
,
name
=
'tags'
,
),
]
circle/setty/migrations/0015_allow_blank_elementcategory_parent.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0014_auto_20160320_1724'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'elementcategory'
,
name
=
'parent_category'
,
field
=
models
.
ForeignKey
(
blank
=
True
,
to
=
'setty.ElementCategory'
,
null
=
True
),
),
]
circle/setty/migrations/0016_auto_20160320_1753.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
import
setty.storage
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0015_allow_blank_elementcategory_parent'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'elementtemplate'
,
name
=
'prototype'
,
field
=
models
.
TextField
(
default
=
b
'<SYNTAX ERROR>'
),
),
migrations
.
AlterField
(
model_name
=
'elementtemplate'
,
name
=
'compatibles'
,
field
=
models
.
ManyToManyField
(
related_name
=
'compatibles_rel_+'
,
to
=
'setty.ElementTemplate'
,
blank
=
True
),
),
migrations
.
AlterField
(
model_name
=
'elementtemplate'
,
name
=
'logo'
,
field
=
models
.
FileField
(
storage
=
setty
.
storage
.
OverwriteStorage
(),
upload_to
=
b
'setty/'
,
blank
=
True
),
),
]
circle/setty/migrations/0017_auto_20160320_1828.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
import
setty.storage
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0016_auto_20160320_1753'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'nginxnode'
,
name
=
'servicenode_ptr'
,
),
migrations
.
AddField
(
model_name
=
'nginxnode'
,
name
=
'webservernode_ptr'
,
field
=
models
.
OneToOneField
(
parent_link
=
True
,
auto_created
=
True
,
primary_key
=
True
,
default
=
None
,
serialize
=
False
,
to
=
'setty.WebServerNode'
),
preserve_default
=
False
,
),
migrations
.
AlterField
(
model_name
=
'elementtemplate'
,
name
=
'logo'
,
field
=
models
.
FileField
(
storage
=
setty
.
storage
.
OverwriteStorage
(),
upload_to
=
b
'setty/'
),
),
]
circle/setty/migrations/0018_auto_20160420_1728.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0017_auto_20160320_1828'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'servicenode'
,
name
=
'machine'
,
),
migrations
.
AddField
(
model_name
=
'servicenode'
,
name
=
'service'
,
field
=
models
.
ForeignKey
(
default
=
None
,
to
=
'setty.Service'
),
),
]
circle/setty/migrations/0019_auto_20160420_2043.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0018_auto_20160420_1728'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'servicenode'
,
name
=
'service'
,
field
=
models
.
ForeignKey
(
related_name
=
'node_service_id'
,
default
=
None
,
to
=
'setty.Service'
),
),
]
circle/setty/migrations/0020_auto_20160420_2132.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'setty'
,
'0019_auto_20160420_2043'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'servicenode'
,
name
=
'service'
,
field
=
models
.
ForeignKey
(
default
=
None
,
to
=
'setty.Service'
),
),
]
circle/setty/migrations/0021_element_real_type.py
0 → 100644
View file @
9ab17d5f
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'contenttypes'
,
'0002_remove_content_type_name'
),
(
'setty'
,
'0020_auto_20160420_2132'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'element'
,
name
=
'real_type'
,
field
=
models
.
ForeignKey
(
default
=
None
,
editable
=
False
,
to
=
'contenttypes.ContentType'
),
),
]
circle/setty/models.py
View file @
9ab17d5f
...
@@ -17,46 +17,101 @@
...
@@ -17,46 +17,101 @@
from
django.db
import
models
from
django.db
import
models
from
django.db.models
import
Model
from
django.db.models
import
Model
from
django.contrib.contenttypes.models
import
ContentType
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
taggit.managers
import
TaggableManager
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
# TODO: derive from object or keep the tricky base function calling?
# TODO: exceptions
SALTSTACK_STATE_FOLDER
=
"/srv/salt"
def
replaceParameter
(
config
,
parameterToReplace
,
newValue
):
configEdited
=
config
.
replace
(
parameterToReplace
,
str
(
newValue
))
return
configEdited
class
Service
(
models
.
Model
):
SERVICE_STATUS_CHOICES
=
((
1
,
'Draft'
),
(
2
,
'Deployed'
))
class
Service
(
Model
):
user
=
models
.
ForeignKey
(
User
)
user
=
models
.
ForeignKey
(
User
)
name
=
models
.
TextField
(
verbose_name
=
"Name"
)
name
=
models
.
TextField
(
verbose_name
=
"Name"
)
status
=
models
.
CharField
(
max_length
=
50
)
status
=
models
.
CharField
(
choices
=
SERVICE_STATUS_CHOICES
,
max_length
=
1
,
default
=
1
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
class
ElementTemplate
(
Model
):
class
ElementCategory
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
50
)
parent_category
=
models
.
ForeignKey
(
'self'
,
on_delete
=
models
.
CASCADE
,
null
=
True
,
blank
=
True
)
def
__unicode__
(
self
):
return
self
.
name
class
ElementTemplate
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
50
)
name
=
models
.
CharField
(
max_length
=
50
)
logo
=
models
.
FileField
(
upload_to
=
'setty/'
,
storage
=
OverwriteStorage
())
logo
=
models
.
FileField
(
upload_to
=
'setty/'
,
storage
=
OverwriteStorage
())
description
=
models
.
TextField
()
description
=
models
.
TextField
()
parameters
=
models
.
TextField
()
compatibles
=
models
.
ManyToManyField
(
'self'
,
blank
=
True
)
compatibles
=
models
.
ManyToManyField
(
'self'
)
category
=
models
.
ForeignKey
(
tags
=
TaggableManager
(
blank
=
True
,
verbose_name
=
_
(
"tags"
))
ElementCategory
,
on_delete
=
models
.
CASCADE
,
null
=
True
)
prototype
=
models
.
TextField
(
default
=
"<SYNTAX ERROR>"
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
# http://stackoverflow.com/questions/929029/how-do-i-access-the-child-classes-of-an-object-in-django-without-knowing-the-name/929982#929982
# Super base class to prevent messing the code in the controller
# it saves the type info to DB, and when the objects are queried, the cast method returns the real class
# not the base
class
Element
(
Model
):
service
=
models
.
ForeignKey
(
Service
,
on_delete
=
models
.
CASCADE
)
class
InheritanceCastModel
(
models
.
Model
):
parameters
=
models
.
TextField
()
real_type
=
models
.
ForeignKey
(
ContentType
,
editable
=
False
,
default
=
None
)
def
save
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
id
:
self
.
real_type
=
self
.
_get_real_type
()
super
(
InheritanceCastModel
,
self
)
.
save
(
*
args
,
**
kwargs
)
def
_get_real_type
(
self
):
return
ContentType
.
objects
.
get_for_model
(
type
(
self
))
def
cast
(
self
):
return
self
.
real_type
.
get_object_for_this_type
(
pk
=
self
.
pk
)
class
Meta
:
abstract
=
True
class
Element
(
InheritanceCastModel
):
display_id
=
models
.
TextField
()
display_id
=
models
.
TextField
()
position_left
=
models
.
FloatField
()
position_left
=
models
.
FloatField
()
position_top
=
models
.
FloatField
()
position_top
=
models
.
FloatField
()
anchor_number
=
models
.
PositiveSmallIntegerField
()
anchor_number
=
models
.
PositiveSmallIntegerField
()
def
__unicode__
(
self
):
def
getDisplayData
(
self
):
return
"
%
s (
%
s)"
%
(
self
.
service
.
name
,
self
.
display_id
)
return
{
'displayId'
:
self
.
display_id
,
'positionLeft'
:
self
.
position_left
,
'positionTop'
:
self
.
position_top
,
'anchorNumber'
:
self
.
anchor_number
}
def
setDisplayData
(
self
,
data
):
self
.
display_id
=
data
[
"displayId"
]
self
.
position_left
=
data
[
"positionLeft"
]
self
.
position_top
=
data
[
"positionTop"
]
self
.
anchor_number
=
data
[
"anchorNumber"
]
class
ElementConnection
(
Model
):
class
ElementConnection
(
models
.
Model
):
target
=
models
.
ForeignKey
(
target
=
models
.
ForeignKey
(
Element
,
Element
,
related_name
=
'target'
,
related_name
=
'target'
,
...
@@ -70,4 +125,265 @@ class ElementConnection(Model):
...
@@ -70,4 +125,265 @@ class ElementConnection(Model):
parameters
=
models
.
TextField
()
parameters
=
models
.
TextField
()
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
"
%
s (
%
d)"
%
(
self
.
target
.
service
.
name
,
self
.
id
)
return
"
%
d"
%
self
.
id
def
getDataDictionary
(
self
):
return
{
'targetEndpoint'
:
self
.
target_endpoint
,
'sourceEndpoint'
:
self
.
source_endpoint
,
'parameters'
:
self
.
parameters
}
class
Machine
(
Element
):
# As a real machine
MACHINE_STATUS_CHOICES
=
(
(
1
,
'Running'
),
(
2
,
'Unreachable'
))
service
=
models
.
ForeignKey
(
Service
,
on_delete
=
models
.
CASCADE
,
related_name
=
"service_id"
)
hostname
=
models
.
TextField
(
null
=
False
)
# also serves as salt-minion id
alias
=
models
.
CharField
(
max_length
=
50
)
#config_file = models.FileField(default=None,upload_to='setty/machine_configs/', storage=OverwriteStorage())
description
=
models
.
TextField
(
default
=
""
)
status
=
models
.
CharField
(
choices
=
MACHINE_STATUS_CHOICES
,
max_length
=
1
)
def
__unicode__
(
self
):
return
"
%
s"
%
self
.
hostname
@staticmethod
def
getInformation
():
return
{
'hostname'
:
hostname
.
get_internal_type
(),
'alias'
:
alias
.
get_internal_type
(),
'description'
:
description
.
get_internal_type
()}
def
getDataDictionary
(
self
):
element_data
=
self
.
getDisplayData
()
self_data
=
{
'hostname'
:
self
.
hostname
,
'alias'
:
self
.
alias
,
'description'
:
self
.
description
}
element_data
.
update
(
self_data
)
return
element_data
def
fromDataDictionary
(
self
,
data
):
self
.
setDisplayData
(
data
)
self
.
hostname
=
data
[
"hostname"
]
self
.
alias
=
data
[
"alias"
]
self
.
description
=
data
[
"description"
]
@staticmethod
def
clone
():
return
Machine
()
class
ServiceNode
(
Element
):
service
=
models
.
ForeignKey
(
Service
,
on_delete
=
models
.
CASCADE
,
default
=
None
)
name
=
models
.
CharField
(
max_length
=
50
)
config_file
=
models
.
FileField
(
default
=
None
,
upload_to
=
'setty/node_configs/'
,
storage
=
OverwriteStorage
())
description
=
models
.
TextField
(
default
=
""
)
machine
=
None
# for deploying
generatedConfig
=
None
def
__unicode__
(
self
):
return
"
%
s"
%
self
.
name
def
getDataDictionary
(
self
):
element_data
=
self
.
getDisplayData
()
self_data
=
{
'name'
:
self
.
name
,
'description'
:
self
.
description
}
element_data
.
update
(
self_data
)
return
element_data
def
fromDataDictionary
(
self
,
data
):
self
.
setDisplayData
(
data
)
self
.
name
=
data
[
'name'
]
self
.
description
=
data
[
'description'
]
@staticmethod
def
getInformation
():
return
{
'name'
:
ServiceNode
.
_meta
.
get_field
(
'name'
)
.
get_internal_type
(),
'description'
:
ServiceNode
.
_meta
.
get_field
(
'description'
)
.
get_internal_type
()}
@staticmethod
def
clone
():
raise
PermissionDenied
def
__cmp__
(
self
,
other
):
return
self
.
getDeploymentPriority
(
self
)
.
__cmp__
(
other
.
getDeploymentPriority
(
other
))
# functions for deployement
def
setMachineForDeploy
(
self
,
machine
):
self
.
machine
=
machine
def
getDeploymentPriority
(
self
):
return
0
def
generateConfigurationRecursively
(
self
):
raise
PermissionDenied
class
WebServerNode
(
ServiceNode
):
useSSL
=
models
.
BooleanField
(
default
=
False
)
listeningPort
=
models
.
PositiveIntegerField
()
def
getDataDictionary
(
self
):
element_data
=
ServiceNode
.
getDataDictionary
(
self
)
self_data
=
{
'useSSL'
:
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'
]
@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
.
update
(
superInformation
)
return
ownInformation
@staticmethod
def
getDeploymentPriority
(
self
):
return
10
def
generateConfiguration
(
self
,
config
=
""
):
config
=
replaceParameter
(
config
,
r"
%%
USE_SSL
%%
"
,
self
.
useSSL
)
config
=
replaceParameter
(
config
,
r"
%%
LISTENING_PORT
%%
"
,
self
.
listeningPort
)
return
config
class
NginxNode
(
WebServerNode
):
worker_connections
=
models
.
PositiveIntegerField
()
def
getDataDictionary
(
self
):
element_data
=
WebServerNode
.
getDataDictionary
(
self
)
self_data
=
{
'worker_connections'
:
self
.
worker_connections
}
element_data
.
update
(
self_data
)
return
element_data
def
fromDataDictionary
(
self
,
data
):
WebServerNode
.
fromDataDictionary
(
self
,
data
)
self
.
worker_connections
=
data
[
'worker_connections'
]
@staticmethod
def
getInformation
():
superInformation
=
WebServerNode
.
getInformation
()
ownInformation
=
{
'worker_connections'
:
NginxNode
.
_meta
.
get_field
(
'worker_connections'
)
.
get_internal_type
()}
ownInformation
.
update
(
superInformation
)
return
ownInformation
@staticmethod
def
clone
():
return
NginxNode
()
def
generateConfigurationRecursively
(
self
):
config
=
str
()
exampleFilePath
=
os
.
path
.
join
(
SALTSTACK_STATE_FOLDER
,
"nginx.example"
)
with
open
(
exampleFilePath
,
'r'
)
as
configFile
:
config
=
configFile
.
read
()
config
=
WebServerNode
.
generateConfiguration
(
self
,
config
)
config
=
replaceParameter
(
config
,
r"
%%
WORKER_CONNECTIONS
%%
"
,
self
.
worker_connections
)
self
.
generatedConfig
=
"nginx_
%
s.sls"
%
self
.
machine
.
hostname
with
open
(
os
.
path
.
join
(
SALTSTACK_STATE_FOLDER
,
self
.
generatedConfig
),
'w'
)
as
generatedConfigFile
:
generatedConfigFile
.
write
(
config
)
configuredNodes
=
[]
configuredNodes
.
append
(
self
)
return
configuredNodes
class
DatabaseNode
(
ServiceNode
):
adminUserName
=
models
.
CharField
(
max_length
=
50
)
adminPassword
=
models
.
CharField
(
max_length
=
50
)
listeningPort
=
models
.
PositiveIntegerField
()
def
getDataDictionary
(
self
):
element_data
=
ServiceNode
.
getDataDictionary
(
self
)
self_data
=
{
'admin_username'
:
self
.
adminUserName
,
'admin_password'
:
self
.
adminPassword
,
'listeningPort'
:
self
.
listeningPort
}
element_data
.
update
(
self_data
)
return
element_data
def
fromDataDictionary
(
self
,
data
):
ServiceNode
.
fromDataDictionary
(
self
,
data
)
self
.
adminUserName
=
data
[
'admin_username'
]
self
.
adminPassword
=
data
[
'admin_password'
]
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
()}
ownInformation
.
update
(
superInformation
)
return
ownInformation
@staticmethod
def
getDeploymentPriority
(
self
):
return
10
def
generateConfiguration
(
self
,
config
=
""
):
config
=
replaceParameter
(
config
,
r"
%%
ADMIN_USERNAME
%%
"
,
self
.
adminUserName
)
config
=
replaceParameter
(
config
,
r"
%%
ADMIN_PASSWORD
%%
"
,
self
.
adminUserName
)
config
=
replaceParameter
(
config
,
r'
%%
LISTENING_PORT
%%
'
,
self
.
listeningPort
)
return
config
class
PostgreSQLNode
(
DatabaseNode
):
@staticmethod
def
clone
():
return
PostgreSQLNode
()
def
generateConfigurationRecursively
(
self
):
config
=
str
()
exampleFilePath
=
os
.
path
.
join
(
SALTSTACK_STATE_FOLDER
,
"postgres.example"
)
with
open
(
exampleFilePath
,
'r'
)
as
configFile
:
config
=
configFile
.
read
()
config
=
DatabaseNode
.
generateConfiguration
(
self
,
config
)
self
.
generatedConfig
=
"postgres_
%
s.sls"
%
self
.
machine
.
hostname
with
open
(
os
.
path
.
join
(
SALTSTACK_STATE_FOLDER
,
self
.
generatedConfig
),
'w'
)
as
generatedConfigFile
:
generatedConfigFile
.
write
(
config
)
return
self
class
MySQLNode
(
DatabaseNode
):
@staticmethod
def
clone
():
return
MySQLNode
()
def
generateConfigurationRecursively
(
self
):
config
=
str
()
exampleFilePath
=
os
.
path
.
join
(
SALTSTACK_STATE_FOLDER
,
"mysql.example"
)
with
open
(
exampleFilePath
,
'r'
)
as
configFile
:
config
=
configFile
.
read
()
config
=
DatabaseNode
.
generateConfiguration
(
self
,
config
)
self
.
generatedConfig
=
"mysql_
%
s.sls"
%
self
.
machine
.
hostname
with
open
(
os
.
path
.
join
(
SALTSTACK_STATE_FOLDER
,
self
.
generatedConfig
),
'w'
)
as
generatedConfigFile
:
generatedConfigFile
.
write
(
config
)
return
self
circle/setty/saltstackhelper.py
0 → 100644
View file @
9ab17d5f
import
salt.loader
import
salt.config
import
salt.runner
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
getAllMinionsGrouped
(
self
):
query_result
=
self
.
salt_runner
.
cmd
(
'manage.status'
,
[]);
return
query_result
def
getAllMinionsUngrouped
(
self
):
query_result
=
self
.
salt_runner
.
cmd
(
'manage.status'
,
[]);
return
query_result
[
"up"
]
+
query_result
[
"down"
]
def
getRunningMinions
(
self
):
return
self
.
salt_runner
.
cmd
(
'manage.up'
,
[]);
def
getUnavailableMinions
(
self
):
return
self
.
salt_runner
.
cmd
(
'manage.down'
,
[]);
def
getMinionBasicHardwareInfo
(
self
,
hostname
):
query_res
=
self
.
salt_localclient
.
cmd
(
hostname
,
'grains.items'
);
if
query_res
:
return
{
'CpuModel'
:
query_res
[
hostname
][
'cpu_model'
],
'CpuArch'
:
query_res
[
hostname
][
'cpuarch'
],
'TotalMemory'
:
query_res
[
hostname
][
'mem_total'
],
'OSDescription'
:
query_res
[
hostname
][
'lsb_distrib_description'
]
}
return
query_res
def
checkMinionExists
(
self
,
hostname
):
query_res
=
self
.
salt_localclient
.
cmd
(
hostname
,
'network.get_hostname'
);
return
query_res
!=
None
def
deploy
(
self
,
hostname
,
configFilePath
):
print
configFilePath
self
.
salt_localclient
.
cmd
(
hostname
,
'state.apply'
,
[
configFilePath
.
split
(
'.'
)[
0
]]
)
\ No newline at end of file
circle/setty/static/setty/apache.jpg
View file @
9ab17d5f
15.9 KB
|
W:
|
H:
15.9 KB
|
W:
|
H:
2-up
Swipe
Onion skin
circle/setty/static/setty/lighttpd.jpg
View file @
9ab17d5f
18.4 KB
|
W:
|
H:
18.4 KB
|
W:
|
H:
2-up
Swipe
Onion skin
circle/setty/static/setty/nginx.jpg
View file @
9ab17d5f
6.02 KB
|
W:
|
H:
6.02 KB
|
W:
|
H:
2-up
Swipe
Onion skin
circle/setty/static/setty/setty.js
View file @
9ab17d5f
/* Settimng up csrf token, touch event and zoom options. */
/* Settimng up csrf token, touch event and zoom options. */
function
getCookie
(
name
)
{
function
getCookie
(
name
)
{
var
cookieValue
=
null
;
var
cookieValue
=
null
;
if
(
document
.
cookie
&&
document
.
cookie
!==
''
)
{
if
(
document
.
cookie
&&
document
.
cookie
!==
''
)
{
...
@@ -82,80 +83,108 @@ jsPlumb.ready(function() {
...
@@ -82,80 +83,108 @@ jsPlumb.ready(function() {
var
nextStepConstraint
=
0
;
var
nextStepConstraint
=
0
;
/* Functions. */
/* Functions. */
setServiceStatus
=
function
(
status
)
{
setServiceStatus
=
function
(
status
)
{
if
(
status
==
"unsaved"
)
{
if
(
status
==
"unsaved"
)
{
$
(
"#serviceStatus"
).
text
(
gettext
(
"Unsaved"
));
$
(
"#serviceStatus"
).
text
(
"Unsaved"
);
}
else
{
}
else
{
$
(
"#serviceStatus"
).
empty
();
$
(
"#serviceStatus"
).
empty
();
}
}
};
};
addInfo
=
function
(
title
,
info
,
object
,
type
)
{
addInfo
=
function
(
title
,
info
,
type
,
object
)
{
mainDiv
=
$
(
"<div>"
,
{
id
=
object
.
attr
(
"id"
).
split
(
"_"
)[
1
];
class
:
"row"
,
$
.
post
(
""
,
{
html
:
$
(
"<div>"
,
{
event
:
"getInformation"
,
class
:
"col-xs-12 text-center"
,
data
:
JSON
.
stringify
({
html
:
row
=
$
(
"<h4>"
,
{
"elementTemplateId"
:
object
.
attr
(
"id"
).
split
(
"_"
)[
1
],
html
:
title
"hostname"
:
object
.
attr
(
"hostname"
)})
})
},
function
(
result
)
{
})
alert
(
result
);
}).
add
(
$
(
"<div>"
,
{
});
class
:
"row"
,
style
:
"margin-top: 16px"
,
/*
html
:
$
(
"<div>"
,
{
$("#informationContainer").empty();
class
:
"col-xs-12 text-center"
,
html
:
row
=
$
(
"<textarea>"
,
{
switch(type){
class
:
"form-control"
,
case "connection":
style
:
"text-align: justify;"
,
div =
rows
:
"18"
,
'<div class="row">' +
id
:
"infoInput"
,
'<div class="col-xs-12 text-center">' +
disabled
:
!
type
,
'<h4>' + title + '</h4>' +
text
:
info
'</div>' +
})
'</div> ' +
})
'<div class="row">' +
}));
'<div class="col-xs-12">' +
controlDiv
=
$
(
"<div>"
,
{
'<textarea class="form-control" rows="28" id="infoInput" placeholder="Config data"></textarea>' +
class
:
"row"
,
'</div>' +
style
:
"margin-top: 16px"
,
'</div> ' +
html
:
$
(
"<div>"
,
{
'<div class="row">' +
class
:
"col-xs-3 text-center"
,
'<div class="col-xs-12 text-center">' +
html
:
$
(
"<button>"
,
{
'<button id="removeConnection" class="btn btn-info">Remove connection</button>' +
class
:
"btn btn-success btn-block"
,
'</div>' +
id
:
"addEndpoint"
,
'</div>';
html
:
gettext
(
"Add endpoint"
)
break;
})
case "element":
}).
add
(
$
(
"<div>"
,
{
div =
class
:
"col-xs-3 text-center"
,
'<div class="row">' +
html
:
$
(
"<button>"
,
{
'<div class="col-xs-12 text-center">' +
class
:
"btn btn-danger btn-block"
,
'<h4>' + title + '</h4>' +
id
:
"removeEndpoint"
,
'</div>' +
html
:
gettext
(
"Delete endpoint"
)
'</div> ' +
})
'<div class="row">' +
})).
add
(
$
(
"<div>"
,
{
'<div class="col-xs-12">' +
class
:
"col-xs-6 text-center"
,
'<textarea class="form-control" rows="24" id="infoInput" placeholder="Config data"></textarea>' +
html
:
$
(
"<button>"
,
{
'</div>' +
class
:
"btn btn-info btn-block"
,
'</div> ' +
id
:
"removeElementFromWorkspace"
,
'<div class="row text-center">' +
html
:
gettext
(
"Remove from workspace"
)
'<label>Endpoints</label>' +
})
'</div>' +
}))
'<div class="row">' +
});
'<div class="col-xs-6 text-center">' +
addElementDiv
=
$
(
"<div>"
,
{
'<button id="addEndpoint" class="btn btn-success"><i class="fa fa-plus"></i></button>' +
class
:
"row"
,
'</div>' +
style
:
"margin-top: 16px"
,
'<div class="col-xs-6 text-center">' +
html
:
$
(
"<div>"
,
{
'<button id="removeEndpoint" class="btn btn-danger"><i class="fa fa-minus"></i></button>' +
class
:
"col-xs-12 text-center"
,
'</div>' +
html
:
row
=
$
(
"<button>"
,
{
'</div> ' +
class
:
"btn btn-success"
,
'<div class="row">' +
id
:
"addElementToWorkspace"
,
'<div class="col-xs-12 text-center">' +
html
:
gettext
(
"Add to workspace"
)
'<button id="removeElementFromWorkspace" class="btn btn-info">Remove from workspace</button>' +
})
'</div>' +
})
'</div>';
});
break;
case "elementTemplate":
$
(
"#informationContainer"
).
html
(
type
?
mainDiv
.
add
(
controlDiv
):
mainDiv
.
add
(
addElementDiv
));
div =
'<div class="row">' +
'<div class="col-xs-12 text-center">' +
'<h4>' + title + '</h4>' +
'</div>' +
'</div> ' +
'<div class="row">' +
'<div class="col-xs-12">' +
'<textarea class="form-control" rows="28" id="infoInput" placeholder="Config data"></textarea>' +
'</div>' +
'</div> ' +
'<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
;
$
(
"#informationContainer"
).
append
(
div
);
$
(
"#infoInput"
).
val
(
info
);
$
(
"#changeInformationDialog"
).
modal
(
'show'
);
$
(
"#changeInformationDialog"
).
modal
(
'show'
);
...
@@ -265,8 +294,10 @@ jsPlumb.ready(function() {
...
@@ -265,8 +294,10 @@ jsPlumb.ready(function() {
anchors
=
element
.
attr
(
"anchors"
);
anchors
=
element
.
attr
(
"anchors"
);
id
=
element
.
attr
(
"id"
);
id
=
element
.
attr
(
"id"
);
for
(
i
=
0
;
i
<
anchors
;
i
++
)
{
for
(
i
=
0
;
i
<
anchors
;
i
++
)
if
(
isConnected
(
i
+
"_"
+
id
))
{
{
if
(
isConnected
(
i
+
"_"
+
id
))
{
return
true
;
return
true
;
}
}
}
}
...
@@ -298,7 +329,7 @@ jsPlumb.ready(function() {
...
@@ -298,7 +329,7 @@ jsPlumb.ready(function() {
addEndpoint
=
function
(
element
)
{
addEndpoint
=
function
(
element
)
{
anchors
=
element
.
attr
(
"anchors"
);
anchors
=
element
.
attr
(
"anchors"
);
if
(
anchors
==
8
)
return
1
;
if
(
anchors
==
8
)
return
;
anchors
++
;
anchors
++
;
...
@@ -314,14 +345,12 @@ jsPlumb.ready(function() {
...
@@ -314,14 +345,12 @@ jsPlumb.ready(function() {
element
.
attr
(
"anchors"
,
anchors
);
element
.
attr
(
"anchors"
,
anchors
);
jsPlumbInstance
.
repaintEverything
();
jsPlumbInstance
.
repaintEverything
();
return
0
;
};
};
removeEndoint
=
function
(
element
)
{
removeEndoint
=
function
(
element
)
{
anchors
=
element
.
attr
(
"anchors"
);
anchors
=
element
.
attr
(
"anchors"
);
if
(
anchors
==
4
)
return
1
;
if
(
anchors
==
4
)
return
;
i
=
--
anchors
;
i
=
--
anchors
;
...
@@ -350,14 +379,13 @@ jsPlumb.ready(function() {
...
@@ -350,14 +379,13 @@ jsPlumb.ready(function() {
element
.
attr
(
"anchors"
,
anchors
);
element
.
attr
(
"anchors"
,
anchors
);
jsPlumbInstance
.
repaintEverything
();
jsPlumbInstance
.
repaintEverything
();
return
0
;
};
};
connectEndpoints
=
function
(
data
)
{
connectEndpoints
=
function
(
data
)
{
connectionObject
=
connectionObject
=
jsPlumbInstance
.
connect
({
jsPlumbInstance
.
connect
({
uuids
:
[
data
[
0
],
data
[
1
]]
source
:
data
[
0
],
target
:
data
[
1
]
});
});
connectionObject
.
parameters
=
data
[
2
];
connectionObject
.
parameters
=
data
[
2
];
...
@@ -381,7 +409,7 @@ jsPlumb.ready(function() {
...
@@ -381,7 +409,7 @@ jsPlumb.ready(function() {
if
(
typeof
idOrInstance
!=
"string"
)
{
if
(
typeof
idOrInstance
!=
"string"
)
{
newInstance
=
idOrInstance
;
newInstance
=
idOrInstance
;
endpoints
=
newInstance
.
attr
(
"anchors"
);
endpoints
=
newInstance
.
attr
(
"anchomNumber"
);
newInstance
.
attr
(
"anchors"
,
0
);
newInstance
.
attr
(
"anchors"
,
0
);
}
else
{
}
else
{
newInstance
=
$
(
'#'
+
idOrInstance
)
newInstance
=
$
(
'#'
+
idOrInstance
)
...
@@ -412,14 +440,42 @@ jsPlumb.ready(function() {
...
@@ -412,14 +440,42 @@ jsPlumb.ready(function() {
return
newInstance
;
return
newInstance
;
};
};
addMachine
=
function
(
idOrInstance
,
newId
,
newPositionY
,
endpoints
,
parameters
,
newPositionX
)
{
newInstance
=
""
;
newInstance
=
$
(
'<div>'
)
.
prop
(
"id"
,
newId
)
.
prop
(
"title"
,
"Right click to delete"
)
.
removeClass
()
.
addClass
(
"element"
)
.
attr
(
"anchors"
,
0
)
.
attr
(
"parameters"
,
parameters
)
.
css
(
"top"
,
newPositionY
)
.
css
(
"left"
,
newPositionX
);
$
(
"#dropContainer"
).
append
(
newInstance
);
for
(
i
=
0
;
i
<=
endpoints
;
i
++
)
{
addEndpoint
(
newInstance
);
}
jsPlumbInstance
.
draggable
(
jsPlumb
.
getSelector
(
".element"
),
{
containment
:
$
(
"#dropContainer"
)
});
setServiceStatus
(
"unsaved"
);
jsPlumbInstance
.
repaintEverything
();
return
newInstance
;
}
removeElement
=
function
(
object
)
{
removeElement
=
function
(
object
)
{
jsPlumbInstance
.
detachAllConnections
(
object
);
jsPlumbInstance
.
detachAllConnections
(
object
);
jsPlumbInstance
.
remove
(
object
.
attr
(
"id"
));
jsPlumbInstance
.
remove
(
object
.
attr
(
"id"
));
};
};
/* Registering events using JsPlumb. */
/* Registering events using JsPlumb. */
jsPlumbInstance
.
bind
(
"connection"
,
function
(
info
)
{
jsPlumbInstance
.
bind
(
"connection"
,
function
(
info
)
{
updateConnections
(
info
.
connection
);
updateConnections
(
info
.
connection
);
...
@@ -468,12 +524,20 @@ jsPlumb.ready(function() {
...
@@ -468,12 +524,20 @@ jsPlumb.ready(function() {
jsPlumbInstance
.
detach
(
info
);
jsPlumbInstance
.
detach
(
info
);
});
});
jsPlumbInstance
.
bind
(
"dblclick"
,
function
(
info
)
{
info
.
setPaintStyle
({
strokeStyle
:
"red"
,
lineWidth
:
8
});
addInfo
(
$
(
"#"
+
info
.
sourceId
.
split
(
'_'
)[
1
]).
attr
(
"alt"
)
+
' - '
+
$
(
"#"
+
info
.
targetId
.
split
(
'_'
)[
1
]).
attr
(
"alt"
),
info
.
parameters
,
"connection"
,
info
);
});
jsPlumbInstance
.
draggable
(
jsPlumb
.
getSelector
(
".element"
),
{
jsPlumbInstance
.
draggable
(
jsPlumb
.
getSelector
(
".element"
),
{
containment
:
$
(
"#dropContainer"
)
containment
:
$
(
"#dropContainer"
)
});
});
/* Registering events using JQuery. */
/* Registering events using JQuery. */
$
(
'body'
).
on
(
'click'
,
'.elementTemplate'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'.elementTemplate'
,
function
()
{
addElement
(
$
(
this
).
attr
(
"id"
),
addElement
(
$
(
this
).
attr
(
"id"
),
...
@@ -493,7 +557,7 @@ jsPlumb.ready(function() {
...
@@ -493,7 +557,7 @@ jsPlumb.ready(function() {
element
.
addClass
(
"elementSelected"
);
element
.
addClass
(
"elementSelected"
);
addInfo
(
element
.
attr
(
"alt"
),
addInfo
(
element
.
attr
(
"alt"
),
element
.
attr
(
"parameters"
),
element
.
attr
(
"parameters"
),
element
,
1
);
"element"
,
element
);
$
(
document
).
scrollTop
(
0
);
$
(
document
).
scrollTop
(
0
);
});
});
...
@@ -510,16 +574,21 @@ jsPlumb.ready(function() {
...
@@ -510,16 +574,21 @@ jsPlumb.ready(function() {
stackIndexer
++
;
stackIndexer
++
;
});
});
$
(
'body'
).
on
(
'keyup'
,
'#infoInput'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#closeInfoPanel'
,
function
()
{
$
(
'#informationPanel'
).
hide
();
$
(
'#dragPanel'
).
show
();
});
$
(
'body'
).
on
(
'keyUp'
,
'#infoInput'
,
function
()
{
setServiceStatus
(
"unsaved"
);
setServiceStatus
(
"unsaved"
);
newParams
=
$
(
"#infoInput"
).
val
();
newParams
=
$
(
"#infoInput"
).
val
();
sharedObject
.
attr
(
"parameters"
,
newParams
);
if
(
type
==
"connection"
)
object
.
parameters
=
newParams
;
if
(
type
==
"element"
)
object
.
attr
(
"parameters"
,
newParams
);
});
});
$
(
'body'
).
on
(
'click'
,
'#addEndpoint'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#addEndpoint'
,
function
()
{
setServiceStatus
(
"unsaved"
);
addEndpoint
(
sharedObject
);
if
(
addEndpoint
(
sharedObject
))
return
;
undoStack
.
splice
(
stackIndexer
,
0
,
removeEndoint
);
undoStack
.
splice
(
stackIndexer
,
0
,
removeEndoint
);
redoStack
.
splice
(
stackIndexer
,
0
,
addEndpoint
);
redoStack
.
splice
(
stackIndexer
,
0
,
addEndpoint
);
objectStack
.
splice
(
stackIndexer
,
0
,
sharedObject
);
objectStack
.
splice
(
stackIndexer
,
0
,
sharedObject
);
...
@@ -528,8 +597,7 @@ jsPlumb.ready(function() {
...
@@ -528,8 +597,7 @@ jsPlumb.ready(function() {
});
});
$
(
'body'
).
on
(
'click'
,
'#removeEndpoint'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#removeEndpoint'
,
function
()
{
setServiceStatus
(
"unsaved"
);
removeEndoint
(
sharedObject
);
if
(
removeEndoint
(
sharedObject
))
return
;
undoStack
.
splice
(
stackIndexer
,
0
,
addEndpoint
);
undoStack
.
splice
(
stackIndexer
,
0
,
addEndpoint
);
redoStack
.
splice
(
stackIndexer
,
0
,
removeEndoint
);
redoStack
.
splice
(
stackIndexer
,
0
,
removeEndoint
);
objectStack
.
splice
(
stackIndexer
,
0
,
sharedObject
);
objectStack
.
splice
(
stackIndexer
,
0
,
sharedObject
);
...
@@ -546,8 +614,6 @@ jsPlumb.ready(function() {
...
@@ -546,8 +614,6 @@ jsPlumb.ready(function() {
objectStack
.
splice
(
stackIndexer
,
0
,
sharedObject
);
objectStack
.
splice
(
stackIndexer
,
0
,
sharedObject
);
stackSize
++
;
stackSize
++
;
stackIndexer
++
;
stackIndexer
++
;
$
(
"#changeInformationDialog"
).
modal
(
'hide'
);
});
});
$
(
'body'
).
on
(
'click'
,
'#removeConnection'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#removeConnection'
,
function
()
{
...
@@ -568,7 +634,7 @@ jsPlumb.ready(function() {
...
@@ -568,7 +634,7 @@ jsPlumb.ready(function() {
});
});
$
(
'body'
).
on
(
'click'
,
'#clearService'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#clearService'
,
function
()
{
//Todo
jsPlumbInstance
.
remove
(
"element"
);
setServiceStatus
(
"unsaved"
);
setServiceStatus
(
"unsaved"
);
elementIndex
=
0
;
elementIndex
=
0
;
...
@@ -593,12 +659,16 @@ jsPlumb.ready(function() {
...
@@ -593,12 +659,16 @@ jsPlumb.ready(function() {
});
});
$
(
'body'
).
on
(
'click'
,
'#addMachineDialog'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#addMachineDialog'
,
function
()
{
// Here comes the ajax post of getting machines
// Here comes the ajax post of getMachineAvailableList
// posting usedhostnames
//
//
// after it, appending obtained content to addmachinedialogbody
});
});
$
(
'body'
).
on
(
'click'
,
'.elementTemplateInfo'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'.elementTemplateInfo'
,
function
()
{
id
=
$
(
this
).
attr
(
"element"
);
id
=
$
(
this
).
attr
(
"element"
);
addInfo
(
$
(
"#"
+
id
).
attr
(
"alt"
),
$
(
"#"
+
id
).
attr
(
"desc"
),
$
(
"#"
+
id
),
0
);
addInfo
(
$
(
"#"
+
id
).
attr
(
"alt"
),
$
(
"#"
+
id
).
attr
(
"desc"
),
"elementTemplate"
,
$
(
"#"
+
id
));
});
});
$
(
'body'
).
on
(
'click'
,
'#serviceName'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#serviceName'
,
function
()
{
...
@@ -622,8 +692,9 @@ jsPlumb.ready(function() {
...
@@ -622,8 +692,9 @@ jsPlumb.ready(function() {
scrollContainer
(
1
);
scrollContainer
(
1
);
});
});
$
(
'body'
).
on
(
'hide.bs.modal'
,
'#changeInformationDialog'
,
function
()
{
$
(
'body'
).
on
(
'hide.bs.modal'
,
'#changeInformationDialog'
,
function
()
{
$
(
'.element'
).
removeClass
(
'elementSelected'
);
$
(
'.element'
).
removeClass
(
'elementSelected'
);
jsPlumbInstance
.
select
().
setPaintStyle
({
strokeStyle
:
'#9932cc'
,
lineWidth
:
8
});
});
});
$
(
'body'
).
on
(
'keyup'
,
'#searchElementTemplate'
,
function
()
{
$
(
'body'
).
on
(
'keyup'
,
'#searchElementTemplate'
,
function
()
{
...
@@ -656,53 +727,52 @@ jsPlumb.ready(function() {
...
@@ -656,53 +727,52 @@ jsPlumb.ready(function() {
var
eventObject
=
window
.
event
?
event
:
e
;
var
eventObject
=
window
.
event
?
event
:
e
;
// Undo (CTRL + Z)
// Undo (CTRL + Z)
if
(
eventObject
.
keyCode
==
90
&&
eventObject
.
ctrlKey
)
{
if
(
eventObject
.
keyCode
==
90
&&
eventObject
.
ctrlKey
)
{
eventObject
.
preventDefault
();
eventObject
.
preventDefault
();
$
(
'#undoMovement'
).
click
();
$
(
'#undoMovement'
).
click
();
}
}
// Redo (CTRL + Y)
// Redo (CTRL + Y)
if
(
eventObject
.
keyCode
==
89
&&
eventObject
.
ctrlKey
)
{
if
(
eventObject
.
keyCode
==
89
&&
eventObject
.
ctrlKey
)
{
eventObject
.
preventDefault
();
eventObject
.
preventDefault
();
$
(
'#redoMovement'
).
click
();
$
(
'#redoMovement'
).
click
();
}
}
// Add element (CTRL + A)
// Add element (CTRL + A)
if
(
eventObject
.
keyCode
==
65
&&
eventObject
.
ctrlKey
)
{
if
(
eventObject
.
keyCode
==
65
&&
eventObject
.
ctrlKey
)
{
eventObject
.
preventDefault
();
eventObject
.
preventDefault
();
$
(
'#showAddElementDialog'
).
click
();
$
(
'#showAddElementDialog'
).
click
();
}
}
// Clean (CTRL + C)
// Clean (CTRL + C)
if
(
eventObject
.
keyCode
==
67
&&
eventObject
.
ctrlKey
)
{
if
(
eventObject
.
keyCode
==
67
&&
eventObject
.
ctrlKey
)
{
eventObject
.
preventDefault
();
eventObject
.
preventDefault
();
$
(
'#clearService'
).
click
();
$
(
'#clearService'
).
click
();
}
}
// Save (CTRL + S)
// Save (CTRL + S)
if
(
eventObject
.
keyCode
==
83
&&
eventObject
.
ctrlKey
)
{
if
(
eventObject
.
keyCode
==
83
&&
eventObject
.
ctrlKey
)
{
eventObject
.
preventDefault
();
eventObject
.
preventDefault
();
$
(
'#saveService'
).
click
();
$
(
'#saveService'
).
click
();
}
}
// Delete (CTRL + D)
// Delete (CTRL + D)
if
(
eventObject
.
keyCode
==
68
&&
eventObject
.
ctrlKey
)
{
if
(
eventObject
.
keyCode
==
68
&&
eventObject
.
ctrlKey
)
{
eventObject
.
preventDefault
();
eventObject
.
preventDefault
();
$
(
'#deleteService'
).
click
();
$
(
'#deleteService'
).
click
();
}
}
// Close dialog (ESC)
if
(
eventObject
.
keyCode
==
27
)
{
eventObject
.
preventDefault
();
$
(
"#changeInformationDialog"
).
modal
(
'hide'
);
$
(
"#addElementDialog"
).
modal
(
'hide'
);
}
});
});
$
(
window
).
on
(
'resize'
,
function
()
{
$
(
window
).
on
(
'resize'
,
function
()
{
$
(
".element"
).
each
(
function
()
{
$
(
".element"
).
each
(
function
()
{
rate
=
(
$
(
this
).
position
().
left
)
/
workspaceWidth
;
rate
=
(
$
(
this
).
position
().
left
)
/
workspaceWidth
;
left
=
rate
*
(
$
(
"#dropContainer"
).
width
());
left
=
rate
*
(
$
(
"#dropContainer"
).
width
());
$
(
this
).
css
(
"left"
,
left
);
$
(
this
).
css
(
"left"
,
left
);
});
});
workspaceWidth
=
$
(
"#dropContainer"
).
width
();
workspaceWidth
=
$
(
"#dropContainer"
).
width
();
...
@@ -710,7 +780,7 @@ jsPlumb.ready(function() {
...
@@ -710,7 +780,7 @@ jsPlumb.ready(function() {
});
});
/* Registering events concerning persistence. */
/* Registering events concerning persistence. */
$
(
'body'
).
on
(
'click'
,
'#saveService'
,
function
()
{
$
(
'body'
).
on
(
'click'
,
'#saveService'
,
function
()
{
serviceName
=
$
(
"#serviceName"
).
text
();
serviceName
=
$
(
"#serviceName"
).
text
();
...
@@ -723,18 +793,16 @@ jsPlumb.ready(function() {
...
@@ -723,18 +793,16 @@ jsPlumb.ready(function() {
"sourceEndpoint"
:
elementConnections
[
index
].
endpoints
[
0
].
getUuid
(),
"sourceEndpoint"
:
elementConnections
[
index
].
endpoints
[
0
].
getUuid
(),
"targetId"
:
elementConnections
[
index
].
targetId
,
"targetId"
:
elementConnections
[
index
].
targetId
,
"targetEndpoint"
:
elementConnections
[
index
].
endpoints
[
1
].
getUuid
(),
"targetEndpoint"
:
elementConnections
[
index
].
endpoints
[
1
].
getUuid
(),
"parameters"
:
elementConnections
[
index
].
parameters
"parameters"
:
elementConnections
[
index
].
parameters
});
});
});
});
$
.
each
(
$
(
".element"
),
function
()
{
$
.
each
(
$
(
".element"
),
function
()
{
instanceSet
.
push
({
instanceSet
.
push
({
"displayId"
:
$
(
this
).
prop
(
"id"
),
"displayId"
:
$
(
this
).
prop
(
"id"
),
"positionLeft"
:
$
(
this
).
position
().
left
/
workspaceWidth
,
"positionLeft"
:
$
(
this
).
position
().
left
/
workspaceWidth
,
"positionTop"
:
$
(
this
).
position
().
top
/
workspaceHeight
,
"positionTop"
:
$
(
this
).
position
().
top
/
workspaceHeight
,
"anchorNumber"
:
$
(
this
).
attr
(
"anchors"
),
"anchorNumber"
:
$
(
this
).
attr
(
"anchors"
),
"parameters"
:
$
(
this
).
attr
(
"parameters"
)
"parameters"
:
$
(
this
).
attr
(
"parameters"
)});
});
});
});
$
.
post
(
""
,
{
$
.
post
(
""
,
{
...
@@ -742,28 +810,42 @@ jsPlumb.ready(function() {
...
@@ -742,28 +810,42 @@ jsPlumb.ready(function() {
data
:
JSON
.
stringify
({
data
:
JSON
.
stringify
({
"serviceName"
:
serviceName
,
"serviceName"
:
serviceName
,
"elementConnections"
:
connectionSet
,
"elementConnections"
:
connectionSet
,
"elements"
:
instanceSet
"elements"
:
instanceSet
,
})
"machines"
:
[]})
//TODO: Dani: add machines here
},
function
(
result
)
{
},
function
(
result
)
{
addMessage
(
result
.
serviceName
+
gettext
(
" saved successfully."
),
"success"
);
addMessage
(
result
.
serviceName
+
gettext
(
" saved successfully."
),
"success"
);
setServiceStatus
(
"saved"
);
setServiceStatus
(
"saved"
);
});
});
});
});
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
if
(
!
$
(
"#dropContainer"
).
length
)
return
;
// Protection for not posting sites that differ from setty sites.
if
(
!
$
(
"#dropContainer"
).
length
)
return
;
$
.
post
(
""
,
{
$
.
post
(
""
,
{
event
:
"loadService"
event
:
"loadService"
},
function
(
result
)
{
},
function
(
result
)
{
$
(
"#serviceName"
).
text
(
result
.
serviceName
);
$
(
"#serviceName"
).
text
(
result
.
serviceName
);
$
.
each
(
result
.
elements
,
function
(
i
,
element
)
{
$
.
each
(
result
.
serviceNodes
,
function
(
i
,
element
)
{
addElement
(
element
.
displayId
.
split
(
'_'
)[
1
],
addElement
(
element
.
displayId
.
split
(
'_'
)[
1
],
element
.
displayId
,
element
.
displayId
,
(
element
.
positionTop
*
workspaceHeight
)
+
"px"
,
(
element
.
positionTop
*
workspaceHeight
)
+
"px"
,
element
.
anchorNumber
,
element
.
parameters
,
(
element
.
positionLeft
*
workspaceWidth
)
+
"px"
);
if
(
elementIndex
<
element
.
displayId
.
split
(
'_'
)[
0
])
elementIndex
=
element
.
displayId
.
split
(
'_'
)[
0
];
elementIndex
++
;
});
$
.
each
(
result
.
machines
,
function
(
i
,
element
)
{
addMachine
(
element
.
displayId
.
split
(
'_'
)[
1
],
element
.
displayId
,
(
element
.
positionTop
*
workspaceHeight
)
+
"px"
,
element
.
anchorNumber
,
element
.
anchorNumber
,
element
.
parameters
,
element
.
parameters
,
(
element
.
positionLeft
*
workspaceWidth
)
+
"px"
);
(
element
.
positionLeft
*
workspaceWidth
)
+
"px"
);
if
(
elementIndex
<
element
.
displayId
.
split
(
'_'
)[
0
])
if
(
elementIndex
<
element
.
displayId
.
split
(
'_'
)[
0
])
elementIndex
=
element
.
displayId
.
split
(
'_'
)[
0
];
elementIndex
=
element
.
displayId
.
split
(
'_'
)[
0
];
elementIndex
++
;
elementIndex
++
;
...
...
circle/setty/static/setty/ubuntu.jpg
View file @
9ab17d5f
9.06 KB
|
W:
|
H:
9.06 KB
|
W:
|
H:
2-up
Swipe
Onion skin
circle/setty/static/setty/wordpress.jpg
View file @
9ab17d5f
19.9 KB
|
W:
|
H:
19.9 KB
|
W:
|
H:
2-up
Swipe
Onion skin
circle/setty/tables.py
View file @
9ab17d5f
circle/setty/views.py
View file @
9ab17d5f
...
@@ -24,7 +24,8 @@ from django.shortcuts import redirect
...
@@ -24,7 +24,8 @@ from django.shortcuts import redirect
from
braces.views
import
LoginRequiredMixin
from
braces.views
import
LoginRequiredMixin
from
django.views.generic
import
TemplateView
,
DeleteView
from
django.views.generic
import
TemplateView
,
DeleteView
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
from
.models
import
Element
,
ElementTemplate
,
ElementConnection
,
Service
from
saltstackhelper
import
*
from
controller
import
*
from
dashboard.views.util
import
FilterMixin
from
dashboard.views.util
import
FilterMixin
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
import
json
import
json
...
@@ -39,6 +40,7 @@ logger = logging.getLogger(__name__)
...
@@ -39,6 +40,7 @@ logger = logging.getLogger(__name__)
class
DetailView
(
LoginRequiredMixin
,
TemplateView
):
class
DetailView
(
LoginRequiredMixin
,
TemplateView
):
template_name
=
"setty/index.html"
template_name
=
"setty/index.html"
salthelper
=
SaltStackHelper
()
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
logger
.
debug
(
'DetailView.get_context_data() called. User:
%
s'
,
logger
.
debug
(
'DetailView.get_context_data() called. User:
%
s'
,
...
@@ -54,88 +56,37 @@ class DetailView(LoginRequiredMixin, TemplateView):
...
@@ -54,88 +56,37 @@ class DetailView(LoginRequiredMixin, TemplateView):
raise
PermissionDenied
raise
PermissionDenied
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
logger
.
debug
(
'DetailView.post() called. User:
%
s'
,
unicode
(
self
.
request
.
user
))
service
=
Service
.
objects
.
get
(
id
=
kwargs
[
'pk'
])
service
=
Service
.
objects
.
get
(
id
=
kwargs
[
'pk'
])
if
self
.
request
.
user
!=
service
.
user
or
not
self
.
request
.
user
.
is_superuser
:
raise
PermissionDenied
if
self
.
request
.
user
==
service
.
user
or
self
.
request
.
user
.
is_superuser
:
result
=
{}
if
self
.
request
.
POST
.
get
(
'event'
)
==
"saveService"
:
eventName
=
self
.
request
.
POST
.
get
(
'event'
)
data
=
json
.
loads
(
self
.
request
.
POST
.
get
(
'data'
))
serviceId
=
kwargs
[
'pk'
]
service
=
Service
.
objects
.
get
(
id
=
kwargs
[
'pk'
])
if
eventName
==
'loadService'
:
service
.
name
=
data
[
'serviceName'
]
result
=
SettyController
.
loadService
(
serviceId
)
service
.
save
()
Element
.
objects
.
filter
(
service
=
service
)
.
delete
()
elif
eventName
==
"deploy"
:
result
=
SettyController
.
deploy
(
serviceId
)
for
element
in
data
[
'elements'
]:
data
=
json
.
loads
(
self
.
request
.
POST
.
get
(
'data'
))
elementObject
=
Element
(
service
=
service
,
parameters
=
element
[
'parameters'
],
display_id
=
element
[
'displayId'
],
position_left
=
element
[
'positionLeft'
],
position_top
=
element
[
'positionTop'
],
anchor_number
=
element
[
'anchorNumber'
]
)
elementObject
.
save
()
for
elementConnection
in
data
[
'elementConnections'
]:
sourceId
=
elementConnection
[
'sourceId'
]
targetId
=
elementConnection
[
'targetId'
]
sourceEndpoint
=
elementConnection
[
'sourceEndpoint'
]
targetEndpoint
=
elementConnection
[
'targetEndpoint'
]
connectionParameters
=
elementConnection
[
'parameters'
]
targetObject
=
Element
.
objects
.
get
(
display_id
=
targetId
,
service
=
service
)
sourceObject
=
Element
.
objects
.
get
(
display_id
=
sourceId
,
service
=
service
)
connectionObject
=
ElementConnection
(
target
=
targetObject
,
source
=
sourceObject
,
target_endpoint
=
targetEndpoint
,
source_endpoint
=
sourceEndpoint
,
parameters
=
connectionParameters
)
connectionObject
.
save
()
return
JsonResponse
({
'serviceName'
:
service
.
name
})
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'
])
elif
self
.
request
.
POST
.
get
(
'event'
)
==
"loadService"
:
return
JsonResponse
(
result
)
service
=
Service
.
objects
.
get
(
id
=
kwargs
[
'pk'
])
elementList
=
Element
.
objects
.
filter
(
service
=
service
)
elementConnectionList
=
ElementConnection
.
objects
.
filter
(
Q
(
target__in
=
elementList
)
|
Q
(
source__in
=
elementList
))
elements
=
[]
elementConnections
=
[]
for
item
in
elementList
:
elements
.
append
({
'parameters'
:
item
.
parameters
,
'displayId'
:
item
.
display_id
,
'positionLeft'
:
item
.
position_left
,
'positionTop'
:
item
.
position_top
,
'anchorNumber'
:
item
.
anchor_number
})
for
item
in
elementConnectionList
:
elementConnections
.
append
({
'targetEndpoint'
:
item
.
target_endpoint
,
'sourceEndpoint'
:
item
.
source_endpoint
,
'parameters'
:
item
.
parameters
})
return
JsonResponse
(
{
'elements'
:
elements
,
'elementConnections'
:
elementConnections
,
'serviceName'
:
service
.
name
})
else
:
raise
PermissionDenied
else
:
raise
PermissionDenied
class
DeleteView
(
LoginRequiredMixin
,
DeleteView
):
class
DeleteView
(
LoginRequiredMixin
,
DeleteView
):
...
@@ -180,11 +131,16 @@ class CreateView(LoginRequiredMixin, TemplateView):
...
@@ -180,11 +131,16 @@ class CreateView(LoginRequiredMixin, TemplateView):
if
not
service_name
:
if
not
service_name
:
service_name
=
"Noname"
service_name
=
"Noname"
service
=
Service
(
try
:
name
=
service_name
,
serviceNameAvailable
=
Service
.
objects
.
get
(
name
=
service_name
)
status
=
"stopped"
,
raise
PermissionDenied
user
=
self
.
request
.
user
except
Service
.
DoesNotExist
:
)
pass
service
=
Service
(
name
=
service_name
,
status
=
1
,
user
=
self
.
request
.
user
)
service
.
save
()
service
.
save
()
return
redirect
(
'setty.views.service-detail'
,
pk
=
service
.
pk
)
return
redirect
(
'setty.views.service-detail'
,
pk
=
service
.
pk
)
...
...
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