Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
CONF
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UvA
CONF
Commits
ebb1fbd4
Commit
ebb1fbd4
authored
Oct 16, 2019
by
Spiros Koulouzis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
try to analyze policies
parent
4ff5fef8
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
288 additions
and
157 deletions
+288
-157
application_example.yaml
TOSCA/application_example.yaml
+14
-1
application_example_output.yaml
TOSCA/application_example_output.yaml
+55
-40
application_example_updated.yaml
TOSCA/application_example_updated.yaml
+10
-1
nodes.yaml
TOSCA/types/nodes.yaml
+12
-0
workspace.xml
drip_planner2/.idea/workspace.xml
+13
-18
planner.py
drip_planner2/src/planner/planner.py
+40
-73
simple_spec_alayzer.py
drip_planner2/src/planner/simple_spec_alayzer.py
+71
-0
specification_analyzer.py
drip_planner2/src/planner/specification_analyzer.py
+34
-0
rpc_server.py
drip_planner2/src/rpc_server.py
+13
-17
setup.py
drip_planner2/src/setup.py
+1
-1
tosca.py
drip_planner2/src/utils/tosca.py
+25
-6
No files found.
TOSCA/application_example.yaml
View file @
ebb1fbd4
...
...
@@ -20,7 +20,7 @@ topology_template:
-
service
:
node
:
mysql
relationship
:
#
type: tosca.relationships.ConnectsTo
type
:
tosca.relationships.ConnectsTo
type
:
tosca.relationships.DependsOn
artifacts
:
image
:
...
...
@@ -58,6 +58,19 @@ topology_template:
-
scalability
:
type
:
tosca.policies.ARTICONF.Performance
targets
:
[
wordpress
]
properties
:
constraint_name
:
cpu_load
max_value
:
90
policies
:
-
scalability
:
type
:
tosca.policies.ARTICONF.FaultTolerance
targets
:
[
mysql
]
properties
:
fault_tolerance_level
:
0
...
...
TOSCA/application_example_output.yaml
View file @
ebb1fbd4
...
...
@@ -9,49 +9,33 @@ imports:
topology_template
:
node_templates
:
beverly_topology
:
interfaces
:
Standard
:
create
:
dumy.yaml
properties
:
domain
:
UvA (Amsterdam, The Netherlands) XO Rack
name
:
name
provider
:
ExoGeni
wordpress
:
type
:
tosca.nodes.ARTICONF.Container.Application.Docker
requirements
:
-
vm
:
capability
:
tosca.capabilities.ARTICONF.VM
node
:
nancy_compute
relationship
:
tosca.relationships.DependsOn
-
vm
:
capability
:
tosca.capabilities.ARTICONF.VM
node
:
charles_compute
relationship
:
tosca.relationships.DependsOn
type
:
tosca.nodes.ARTICONF.VM.topology
charles_compute
:
interfaces
:
Standard
:
create
:
dumy.yaml
-
service
:
node
:
mysql
relationship
:
#type: tosca.relationships.ConnectsTo
type
:
tosca.relationships.DependsOn
artifacts
:
image
:
file
:
wordpress:latest
type
:
tosca.artifacts.Deployment.Image.Container.Docker
repository
:
docker_hub
properties
:
cpu_frequency
:
2.9 GHz
disk_size
:
25000 MB
host_name
:
vm
mem_size
:
3000 MB
num_cpus
:
1
type
:
tosca.nodes.ARTICONF.VM.Compute
heidi_kubernetes
:
interfaces
:
Standard
:
create
:
interfaces/playbooks/kubernetes_install.yaml
ports
:
-
"
8000:80"
environment
:
WORDPRESS_DB_HOST
:
mysql:3306
WORDPRESS_DB_USER
:
wordpress
WORDPRESS_DB_PASSWORD
:
wordpress
WORDPRESS_DB_NAME
:
wordpress
requirements
:
-
host
:
capability
:
tosca.capabilities.Scalable
node
:
beverly_topology
relationship
:
tosca.relationships.HostedOn
-
host
:
capability
:
tosca.capabilities.Compute
node
:
beverly_topology
relationship
:
tosca.relationships.HostedOn
type
:
tosca.nodes.ARTICONF.Orchestrator.Kubernetes
capability
:
tosca.capabilities.ARTICONF.Orchestrator
node
:
heidi_kubernetes
relationship
:
tosca.relationships.HostedOn
mysql
:
artifacts
:
image
:
...
...
@@ -71,7 +55,38 @@ topology_template:
capability
:
tosca.capabilities.ARTICONF.Orchestrator
node
:
heidi_kubernetes
relationship
:
tosca.relationships.HostedOn
type
:
tosca.nodes.ARTICONF.Container.Application.Docker
type
:
tosca.nodes.ARTICONF.Container.Application.Docker
heidi_kubernetes
:
interfaces
:
Standard
:
create
:
interfaces/playbooks/kubernetes_install.yaml
requirements
:
-
host
:
capability
:
tosca.capabilities.Scalable
node
:
beverly_topology
relationship
:
tosca.relationships.HostedOn
-
host
:
capability
:
tosca.capabilities.Compute
node
:
beverly_topology
relationship
:
tosca.relationships.HostedOn
type
:
tosca.nodes.ARTICONF.Orchestrator.Kubernetes
beverly_topology
:
interfaces
:
Standard
:
create
:
dumy.yaml
properties
:
domain
:
UvA (Amsterdam, The Netherlands) XO Rack
name
:
name
provider
:
ExoGeni
requirements
:
-
vm
:
capability
:
tosca.capabilities.ARTICONF.VM
node
:
nancy_compute
relationship
:
tosca.relationships.DependsOn
type
:
tosca.nodes.ARTICONF.VM.topology
nancy_compute
:
interfaces
:
Standard
:
...
...
TOSCA/application_example_updated.yaml
View file @
ebb1fbd4
...
...
@@ -20,7 +20,7 @@ topology_template:
-
service
:
node
:
mysql
relationship
:
#
type: tosca.relationships.ConnectsTo
type
:
tosca.relationships.ConnectsTo
type
:
tosca.relationships.DependsOn
artifacts
:
image
:
...
...
@@ -75,6 +75,15 @@ topology_template:
-
scalability
:
type
:
tosca.policies.ARTICONF.Performance
targets
:
[
wordpress
]
properties
:
constraint_name
:
cpu_load
max_value
:
90
-
faultTolerance
:
type
:
tosca.policies.ARTICONF.FaultTolerance
targets
:
[
mysql
]
properties
:
level
:
1
...
...
TOSCA/types/nodes.yaml
View file @
ebb1fbd4
...
...
@@ -51,6 +51,18 @@ node_types:
host
:
type
:
tosca.capabilities.ARTICONF.Orchestrator
occurrences
:
[
1
,
1
]
properties
:
masters_num
:
type
:
integer
required
:
true
constraints
:
-
greater_or_equal
:
1
workers_num
:
type
:
integer
required
:
true
constraints
:
-
greater_or_equal
:
1
tosca.nodes.ARTICONF.Orchestrator.Kubernetes
:
...
...
drip_planner2/.idea/workspace.xml
View file @
ebb1fbd4
...
...
@@ -2,22 +2,17 @@
<project
version=
"4"
>
<component
name=
"ChangeListManager"
>
<list
default=
"true"
id=
"462ede19-adfe-472b-975e-fefefa973fe0"
name=
"Default Changelist"
comment=
"slolved cap error"
>
<change
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/model/Message.java"
afterDir=
"false"
/>
<change
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/model/MessageParameter.java"
afterDir=
"false"
/>
<change
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/rpc/DRIPCaller.java"
afterDir=
"false"
/>
<change
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/rpc/PlannerCaller.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-api/src/main/java/nl/uva/sne/drip/api/rpc/DRIPCaller.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-api/src/main/java/nl/uva/sne/drip/api/rpc/DRIPCaller.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-commons/src/main/java/nl/uva/sne/drip/drip/commons/data/internal/Message.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-commons/src/main/java/nl/uva/sne/drip/drip/commons/data/internal/Message.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/pom.xml"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/pom.xml"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/Swagger2SpringBoot.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/Swagger2SpringBoot.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/api/PlannerApiController.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/api/PlannerApiController.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/configuration/MongoConfig.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/configuration/MongoConfig.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/CredentialService.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/CredentialService.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/PlannerService.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/PlannerService.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/ToscaTemplateService.java"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/ToscaTemplateService.java"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../drip-manager/src/main/resources/application.properties"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../drip-manager/src/main/resources/application.properties"
afterDir=
"false"
/>
<change
afterPath=
"$PROJECT_DIR$/src/planner/simple_spec_alayzer.py"
afterDir=
"false"
/>
<change
afterPath=
"$PROJECT_DIR$/src/planner/specification_analyzer.py"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../TOSCA/application_example.yaml"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../TOSCA/application_example.yaml"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../TOSCA/application_example_output.yaml"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../TOSCA/application_example_output.yaml"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../TOSCA/application_example_updated.yaml"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../TOSCA/application_example_updated.yaml"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/../TOSCA/types/nodes.yaml"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/../TOSCA/types/nodes.yaml"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/.idea/workspace.xml"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/.idea/workspace.xml"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/src/planner/planner.py"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/src/planner/planner.py"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/src/rpc_server.py"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/src/rpc_server.py"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/src/setup.py"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/src/setup.py"
afterDir=
"false"
/>
<change
beforePath=
"$PROJECT_DIR$/src/utils/tosca.py"
beforeDir=
"false"
afterPath=
"$PROJECT_DIR$/src/utils/tosca.py"
afterDir=
"false"
/>
</list>
<option
name=
"EXCLUDED_CONVERTED_TO_IGNORED"
value=
"true"
/>
<option
name=
"SHOW_DIALOG"
value=
"false"
/>
...
...
@@ -103,7 +98,7 @@
<option
name=
"ADD_CONTENT_ROOTS"
value=
"true"
/>
<option
name=
"ADD_SOURCE_ROOTS"
value=
"true"
/>
<option
name=
"SCRIPT_NAME"
value=
"$PROJECT_DIR$/src/rpc_server.py"
/>
<option
name=
"PARAMETERS"
value=
"
localhost planner_queue
"
/>
<option
name=
"PARAMETERS"
value=
"
test_local
"
/>
<option
name=
"SHOW_COMMAND_LINE"
value=
"false"
/>
<option
name=
"EMULATE_TERMINAL"
value=
"false"
/>
<option
name=
"MODULE_MODE"
value=
"false"
/>
...
...
@@ -221,9 +216,9 @@
<option
name=
"timeStamp"
value=
"1"
/>
</line-breakpoint>
<line-breakpoint
enabled=
"true"
suspend=
"THREAD"
type=
"python-line"
>
<url>
file://$PROJECT_DIR$/src/
rpc_server
.py
</url>
<line>
95
</line>
<option
name=
"timeStamp"
value=
"
1
1"
/>
<url>
file://$PROJECT_DIR$/src/
utils/tosca
.py
</url>
<line>
32
</line>
<option
name=
"timeStamp"
value=
"
5
1"
/>
</line-breakpoint>
</breakpoints>
<default-breakpoints>
...
...
drip_planner2/src/planner/planner.py
View file @
ebb1fbd4
import
logging
from
toscaparser.nodetemplate
import
NodeTemplate
from
toscaparser.tosca_template
import
ToscaTemplate
import
networkx
as
nx
from
toscaparser.topology_template
import
TopologyTemplate
import
operator
from
planner.spec_service
import
*
from
utils.tosca
import
*
from
utils
import
tosca
as
tosca_util
from
src.planner.simple_spec_alayzer
import
SimpleAnalyzer
from
src.planner.spec_service
import
*
from
src.utils.tosca
import
*
from
src.planner.specification_analyzer
import
*
from
src.utils
import
tosca
as
tosca_util
import
matplotlib.pyplot
as
plt
class
Planner
:
def
__init__
(
self
,
path
):
self
.
template
=
ToscaTemplate
(
path
)
self
.
tosca_node_types
=
self
.
template
.
nodetemplates
[
0
]
.
type_definition
.
TOSCA_DEF
self
.
all_custom_def
=
self
.
template
.
nodetemplates
[
0
]
.
custom_def
self
.
all_nodes
=
{}
self
.
all_nodes
.
update
(
self
.
tosca_node_types
.
items
())
self
.
all_nodes
.
update
(
self
.
all_custom_def
.
items
())
def
__init__
(
self
,
path
,
spec_service
):
self
.
t
osca_t
emplate
=
ToscaTemplate
(
path
)
self
.
tosca_node_types
=
self
.
t
osca_t
emplate
.
nodetemplates
[
0
]
.
type_definition
.
TOSCA_DEF
self
.
all_custom_def
=
self
.
t
osca_t
emplate
.
nodetemplates
[
0
]
.
custom_def
self
.
all_node
_type
s
=
{}
self
.
all_node
_type
s
.
update
(
self
.
tosca_node_types
.
items
())
self
.
all_node
_type
s
.
update
(
self
.
all_custom_def
.
items
())
self
.
required_nodes
=
[]
props
=
{
'kb_url'
:
"https://host"
}
self
.
spec_service
=
SpecService
(
props
)
# graph = self.build_graph(template.nodetemplates)
self
.
spec_service
=
spec_service
def
add_required_nodes_to_template
(
self
,
required_nodes
):
for
req_node
in
required_nodes
:
node_template
=
tosca_util
.
node_type_2_node_template
(
req_node
)
self
.
template
.
nodetemplates
.
append
(
node_template
)
return
self
.
template
self
.
t
osca_t
emplate
.
nodetemplates
.
append
(
node_template
)
return
self
.
t
osca_t
emplate
def
set_infrastructure_specifications
(
self
,
required_nodes
):
# Start bottom up and (node without requirements leaf) and find the root of the graph.
# Get root performance, version requirements and set specs to required node
# required_nodes = self.set_vm_specifications(required_nodes)
# required_nodes = self.set_topology_specifications(required_nodes)
return
required_nodes
def
set_vm_specifications
(
self
,
required_nodes
):
for
node
in
required_nodes
:
node_type_name
=
tosca_util
.
get_node_type_name
(
node
)
if
node_type_name
==
'tosca.nodes.ARTICONF.VM.Compute'
:
node_template_props
=
{
'properties'
:
{}}
node_properties
=
tosca_util
.
get_node_properties
(
node
)
for
node_type_prop_key
in
node_properties
:
node_template_prop
=
self
.
get_node_template_property
(
node_type_prop_key
,
node_properties
[
node_type_prop_key
])
node_template_props
[
'properties'
][
node_type_prop_key
]
=
node_template_prop
node
=
tosca_util
.
set_node_properties
(
node
,
node_template_props
)
logging
.
info
(
'node: '
+
node_type_name
+
' properties: '
+
str
(
node_template_props
))
specification_analyzer
=
SimpleAnalyzer
(
required_nodes
,
self
.
tosca_template
)
required_nodes
=
specification_analyzer
.
set_node_specifications
()
return
required_nodes
def
get_node_template_property
(
self
,
prop_key
,
node_prop_dict
):
...
...
@@ -71,7 +57,8 @@ class Planner:
# Resolve requirements. Go over all nodes and recursively resolve requirements till node has no requirements
# e.g. docker -> k8s -> cluster -> vm
def
resolve_requirements
(
self
):
for
node
in
self
.
template
.
nodetemplates
:
for
node
in
self
.
tosca_template
.
nodetemplates
:
logging
.
info
(
'Resolving requirements for: '
+
node
.
name
)
self
.
add_required_nodes
(
node
)
return
self
.
required_nodes
...
...
@@ -85,42 +72,22 @@ class Planner:
# Only add node that is not in node_templates
matching_node_type_name
=
next
(
iter
(
matching_node
))
# capable_node_template = self.node_type_2_node_template(matching_node)
matching_node_type_name
=
next
(
iter
(
matching_node
))
matching_node_template
=
tosca_util
.
node_type_2_node_template
(
matching_node
)
node
=
self
.
add_missing_requirements
(
node
,
missing_requirements
,
matching_node_template
.
name
)
if
not
tosca_util
.
contains_node_type
(
self
.
required_nodes
,
matching_node_type_name
):
matching_node_type_name
=
next
(
iter
(
matching_node
))
node
=
self
.
add_missing_requirements
(
node
,
missing_requirements
,
matching_node_type_name
)
logging
.
info
(
'Adding: '
+
str
(
matching_node_type_name
))
logging
.
info
(
' Adding: '
+
str
(
matching_node_template
.
name
))
self
.
required_nodes
.
append
(
matching_node
)
# Find matching nodes for the new node's requirements
self
.
add_required_nodes
(
matching_node
)
def
build_graph
(
self
,
nodetemplates
):
graph
=
nx
.
Graph
()
for
node
in
nodetemplates
:
graph
.
add_node
(
node
.
name
)
for
req
in
node
.
requirements
:
req_name
=
next
(
iter
(
req
))
trg_node_name
=
req
[
req_name
][
'node'
]
for
key
in
req
[
req_name
]:
if
key
!=
'node'
:
dict_req
=
req
[
req_name
][
key
]
if
isinstance
(
dict_req
,
dict
):
graph
.
add_edge
(
node
.
name
,
trg_node_name
,
key
=
key
,
attr_dict
=
dict_req
)
elif
isinstance
(
dict_req
,
str
):
graph
.
add_edge
(
node
.
name
,
trg_node_name
,
key
=
key
,
attr_dict
=
{
'type'
:
dict_req
})
print
(
"Nodes: "
+
str
(
graph
.
nodes
()))
print
(
"Edges: "
+
str
(
graph
.
edges
()))
print
(
"Edges: "
+
str
(
graph
.
edges
(
data
=
True
)))
return
graph
def
get_missing_requirements
(
self
,
node
):
node_type_name
=
tosca_util
.
get_node_type_name
(
node
)
node_requirements
=
tosca_util
.
get_node_requirements
(
node
)
parent_type_requirements
=
tosca_util
.
get_parent_type_requirements
(
node
,
self
.
all_nodes
)
parent_type_requirements
=
tosca_util
.
get_parent_type_requirements
(
node
,
self
.
all_node
_type
s
)
logging
.
debug
(
'Looking for requirements for node: '
+
node_type_name
)
def_type
=
self
.
all_nodes
[
node_type_name
]
def_type
=
self
.
all_node
_type
s
[
node_type_name
]
def_requirements
=
[]
if
'requirements'
in
def_type
.
keys
():
...
...
@@ -153,14 +120,14 @@ class Planner:
def
get_node_types_by_capability
(
self
,
cap
):
candidate_nodes
=
{}
for
tosca_node_type
in
self
.
all_nodes
:
if
tosca_node_type
.
startswith
(
'tosca.nodes'
)
and
'capabilities'
in
self
.
all_nodes
[
tosca_node_type
]:
for
tosca_node_type
in
self
.
all_node
_type
s
:
if
tosca_node_type
.
startswith
(
'tosca.nodes'
)
and
'capabilities'
in
self
.
all_node
_type
s
[
tosca_node_type
]:
logging
.
debug
(
' Node: '
+
str
(
tosca_node_type
))
for
caps
in
self
.
all_nodes
[
tosca_node_type
][
'capabilities'
]:
for
caps
in
self
.
all_node
_type
s
[
tosca_node_type
][
'capabilities'
]:
logging
.
debug
(
' '
+
str
(
self
.
all_nodes
[
tosca_node_type
][
'capabilities'
][
caps
][
'type'
])
+
' == '
+
cap
)
if
self
.
all_nodes
[
tosca_node_type
][
'capabilities'
][
caps
][
'type'
]
==
cap
:
candidate_nodes
[
tosca_node_type
]
=
self
.
all_nodes
[
tosca_node_type
]
self
.
all_node
_type
s
[
tosca_node_type
][
'capabilities'
][
caps
][
'type'
])
+
' == '
+
cap
)
if
self
.
all_node
_type
s
[
tosca_node_type
][
'capabilities'
][
caps
][
'type'
]
==
cap
:
candidate_nodes
[
tosca_node_type
]
=
self
.
all_node
_type
s
[
tosca_node_type
]
logging
.
debug
(
' candidate_node: '
+
str
(
tosca_node_type
))
candidate_child_nodes
=
{}
...
...
@@ -182,7 +149,7 @@ class Planner:
for
req
in
missing_requirements
:
for
key
in
req
:
capability
=
req
[
key
][
'capability'
]
logging
.
info
(
'Looking for nodes with capability: '
+
capability
)
logging
.
info
(
'
Looking for nodes with capability: '
+
capability
)
# Find all nodes in the definitions that have the capability: capability
capable_nodes
=
self
.
get_node_types_by_capability
(
capability
)
if
capable_nodes
:
...
...
@@ -197,7 +164,7 @@ class Planner:
matching_requirement_count
+=
1
number_of_matching_requirement
[
node_type
]
=
matching_requirement_count
logging
.
info
(
' Found: '
+
str
(
node_type
))
logging
.
info
(
'
Found: '
+
str
(
node_type
))
matching_nodes
.
update
(
capable_nodes
)
else
:
logging
.
error
(
'Did not find node with required capability: '
+
str
(
req
[
key
][
'capability'
]))
...
...
@@ -214,10 +181,10 @@ class Planner:
def
get_child_nodes
(
self
,
parent_node_type_name
):
child_nodes
=
{}
for
tosca_node_type
in
self
.
all_nodes
:
if
tosca_node_type
.
startswith
(
'tosca.nodes'
)
and
'derived_from'
in
self
.
all_nodes
[
tosca_node_type
]:
if
parent_node_type_name
==
self
.
all_nodes
[
tosca_node_type
][
'derived_from'
]:
child_nodes
[
tosca_node_type
]
=
self
.
all_nodes
[
tosca_node_type
]
for
tosca_node_type
in
self
.
all_node
_type
s
:
if
tosca_node_type
.
startswith
(
'tosca.nodes'
)
and
'derived_from'
in
self
.
all_node
_type
s
[
tosca_node_type
]:
if
parent_node_type_name
==
self
.
all_node
_type
s
[
tosca_node_type
][
'derived_from'
]:
child_nodes
[
tosca_node_type
]
=
self
.
all_node
_type
s
[
tosca_node_type
]
return
child_nodes
def
add_missing_requirements
(
self
,
node
,
missing_requirements
,
capable_node_name
):
...
...
drip_planner2/src/planner/simple_spec_alayzer.py
0 → 100644
View file @
ebb1fbd4
from
src.utils
import
tosca
as
tosca_util
from
src.planner.specification_analyzer
import
SpecificationAnalyzer
import
networkx
as
nx
import
logging
def
set_node_properties_for_policy
(
affected_node
,
policy
):
ancestors_types
=
tosca_util
.
get_all_ancestors_types
(
affected_node
)
if
affected_node
.
type
==
'tosca.nodes.ARTICONF.Orchestrator'
:
if
policy
.
type
==
'tosca.policies.ARTICONF.Performance.CPU'
:
logging
.
info
(
'Do placement'
)
return
affected_node
def
set_specs
(
node_name
,
policy
,
nodes_in_template
):
for
node
in
nodes_in_template
:
if
node
.
name
==
node_name
:
affected_node
=
node
break
logging
.
info
(
'node to implement policy: '
+
str
(
affected_node
.
type
))
affected_node
=
set_node_properties_for_policy
(
affected_node
,
policy
)
return
affected_node
class
SimpleAnalyzer
(
SpecificationAnalyzer
):
def
__init__
(
self
,
required_nodes
,
tosca_template
):
super
(
SimpleAnalyzer
,
self
)
.
__init__
(
required_nodes
,
tosca_template
)
def
set_node_specifications
(
self
):
# nx.draw(g, with_labels=True)
# plt.savefig("/tmp/graph.png")
# plt.show()
nodes_to_implement_policy
=
self
.
get_nodes_to_implement_policy
()
for
node_name
in
nodes_to_implement_policy
:
policy
=
nodes_to_implement_policy
[
node_name
]
affected_node
=
set_specs
(
node_name
,
policy
,
self
.
nodes_in_template
)
return
self
.
required_nodes
def
get_nodes_to_implement_policy
(
self
):
nodes_to_implement_policy
=
{}
for
policy
in
self
.
tosca_template
.
policies
:
for
target
in
policy
.
targets
:
for
leaf
in
self
.
leaf_nodes
:
for
affected_node_name
in
(
nx
.
shortest_path
(
self
.
g
,
source
=
target
,
target
=
leaf
)):
if
affected_node_name
not
in
nodes_to_implement_policy
:
policy_list
=
[]
nodes_to_implement_policy
[
affected_node_name
]
=
policy_list
policy_list
=
nodes_to_implement_policy
[
affected_node_name
]
policy_list
.
append
(
policy
)
nodes_to_implement_policy
[
affected_node_name
]
=
policy_list
return
nodes_to_implement_policy
def
build_graph
(
self
,
node_templates
):
graph
=
nx
.
DiGraph
()
for
node
in
node_templates
:
graph
.
add_node
(
node
.
name
,
attr_dict
=
node
.
entity_tpl
)
for
req
in
node
.
requirements
:
req_name
=
next
(
iter
(
req
))
req_node_name
=
req
[
req_name
][
'node'
]
if
'type'
in
req
[
req_name
][
'relationship'
]:
relationship_type
=
req
[
req_name
][
'relationship'
][
'type'
]
else
:
relationship_type
=
req
[
req_name
][
'relationship'
]
graph
.
add_edge
(
node
.
name
,
req_node_name
,
relationship
=
relationship_type
)
return
graph
drip_planner2/src/planner/specification_analyzer.py
0 → 100644
View file @
ebb1fbd4
from
abc
import
abstractmethod
,
ABCMeta
from
src.utils
import
tosca
as
tosca_util
class
SpecificationAnalyzer
(
metaclass
=
ABCMeta
):
def
__init__
(
self
,
required_nodes
,
tosca_template
):
self
.
tosca_template
=
tosca_template
self
.
tosca_node_types
=
self
.
tosca_template
.
nodetemplates
[
0
]
.
type_definition
.
TOSCA_DEF
self
.
all_custom_def
=
self
.
tosca_template
.
nodetemplates
[
0
]
.
custom_def
self
.
all_node_types
=
{}
self
.
all_node_types
.
update
(
self
.
tosca_node_types
.
items
())
self
.
all_node_types
.
update
(
self
.
all_custom_def
.
items
())
self
.
required_nodes
=
required_nodes
self
.
nodes_in_template
=
[]
for
req_node
in
required_nodes
:
node_template
=
tosca_util
.
node_type_2_node_template
(
req_node
)
self
.
nodes_in_template
.
append
(
node_template
)
self
.
nodes_in_template
+=
tosca_template
.
nodetemplates
self
.
g
=
self
.
build_graph
(
self
.
nodes_in_template
)
self
.
root_nodes
=
[]
self
.
leaf_nodes
=
[]
for
node_name
,
degree
in
self
.
g
.
in_degree
():
if
degree
==
0
:
self
.
root_nodes
.
append
(
node_name
)
for
node_name
,
degree
in
self
.
g
.
out_degree
():
if
degree
==
0
:
self
.
leaf_nodes
.
append
(
node_name
)
@
abstractmethod
def
set_node_specifications
(
self
):
raise
NotImplementedError
(
'Must implement upload in subclasses'
)
drip_planner2/src/rpc_server.py
View file @
ebb1fbd4
...
...
@@ -2,22 +2,17 @@
# To change this template file, choose Tools | Templates
# and open the template in the editor.
import
json
import
logging
import
os
import
os.path
from
builtins
import
print
import
yaml
from
planner.basic_planner
import
*
from
planner.planner
import
*
import
pika
import
sys
import
tempfile
import
time
import
logging
import
base64
from
utils
import
tosca
as
tosca_util
import
pika
from
src.planner.basic_planner
import
*
from
src.planner.planner
import
*
from
src.planner.spec_service
import
SpecService
from
src.utils
import
tosca
as
tosca_util
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -114,14 +109,15 @@ def handle_delivery(message):
if
__name__
==
"__main__"
:
logging
.
basicConfig
(
level
=
logging
.
INFO
)
if
sys
.
argv
[
1
]
==
"test_local"
:
tosca_file_path
=
"../../TOSCA/application_example.yaml"
# planner = BasicPlanner(tosca_file_path)
test_planner
=
Planner
(
tosca_file_path
)
tosca_file_path
=
"../../TOSCA/application_example_updated.yaml"
conf
=
{
'url'
:
"http://host"
}
spec_service
=
SpecService
(
conf
)
test_planner
=
Planner
(
tosca_file_path
,
spec_service
)
test_planner_required_nodes
=
test_planner
.
resolve_requirements
()
test_planner_required_nodes
=
test_planner
.
set_infrastructure_specifications
(
test_planner_required_nodes
)
test_planner
.
add_required_nodes_to_template
(
test_planner_required_nodes
)
template
=
tosca_util
.
get_tosca_template_
as_yml
(
test_planner
.
template
)
logger
.
info
(
"template ----:
\n
"
+
template
)
template
=
tosca_util
.
get_tosca_template_
2_topology_template
(
test_planner
.
tosca_
template
)
#
logger.info("template ----: \n" + template)
else
:
logger
.
info
(
"Input args: "
+
sys
.
argv
[
0
]
+
' '
+
sys
.
argv
[
1
]
+
' '
+
sys
.
argv
[
2
])
channel
=
init_chanel
(
sys
.
argv
)
...
...
drip_planner2/src/setup.py
View file @
ebb1fbd4
...
...
@@ -6,7 +6,7 @@ setup (
packages
=
find_packages
(),
# Declare your packages' dependencies here, for eg:
install_requires
=
[
'
foo>=3
'
],
install_requires
=
[
'
matplotlib>=3.1.1
'
],
# Fill in these to make your Egg ready for upload to
# PyPI
...
...
drip_planner2/src/utils/tosca.py
View file @
ebb1fbd4
from
toscaparser.nodetemplate
import
NodeTemplate
from
utils.TOSCA_parser
import
TOSCAParser
import
yaml
import
logging
node_type_key_names_to_remove
=
[
'capabilities'
,
'derived_from'
]
...
...
@@ -28,7 +30,7 @@ def get_parent_type(node):
if
isinstance
(
node
,
NodeTemplate
):
parent_type
=
node
.
parent_type
elif
isinstance
(
node
,
dict
):
parent_type
=
node
[
n
ode_type_name
][
'derived_from'
]
parent_type
=
node
[
n
ext
(
iter
(
node
))
][
'derived_from'
]
return
parent_type
...
...
@@ -77,10 +79,20 @@ def node_type_2_node_template(node_type):
return
NodeTemplate
(
name
,
nodetemplate_dict
,
node_type
)
def
get_tosca_template_
as_yml
(
template
):
def
get_tosca_template_
2_topology_template
(
template
):
tp
=
TOSCAParser
()
yaml_str
=
tp
.
tosca_template2_yaml
(
template
)
return
yaml_str
tosca_template_dict
=
yaml
.
load
(
yaml_str
,
Loader
=
yaml
.
FullLoader
)
tosca_template
=
tosca_template_dict
[
'tosca_template'
]
tosca_template_dict
.
pop
(
'tosca_template'
)
tosca_template_dict
[
'topology_template'
]
=
tosca_template
if
template
.
policies
and
'policies'
not
in
tosca_template_dict
[
'topology_template'
]:
policies_list
=
[]
for
policy
in
template
.
policies
:
policies_list
.
append
(
policy
.
entity_tpl
)
tosca_template_dict
[
'topology_template'
][
'policies'
]
=
policies_list
return
yaml
.
dump
(
tosca_template_dict
)
def
contains_node_type
(
node_types_list
,
node_type_name
):
...
...
@@ -97,11 +109,18 @@ def contains_node_type(node_types_list, node_type_name):
def
get_node_properties
(
node
):
node_type_name
=
get_node_type_name
(
node
)
node_type_name
=
get_node_type_name
(
node
)
return
node
[
node_type_name
][
'properties'
]
def
set_node_properties
(
node
,
properties
):
def
set_node_properties
(
node
,
properties
):
node_type_name
=
get_node_type_name
(
node
)
node
[
node_type_name
][
'properties'
]
=
properties
return
node
\ No newline at end of file
return
node
def
get_all_ancestors_types
(
child_node
):
logging
.
info
(
'child_node: '
+
str
(
child_node
.
type
))
parent_type
=
get_parent_type
(
child_node
)
# logging.info('child_node.parent_type: ' + str(parent_type))
return
None
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