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
9551f6d6
Commit
9551f6d6
authored
Oct 04, 2019
by
Spiros Koulouzis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
split methods to util and set node properties to default
parent
6606fbe8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
206 additions
and
98 deletions
+206
-98
planner.py
drip_planner2/src/planner/planner.py
+89
-89
spec_service.py
drip_planner2/src/planner/spec_service.py
+4
-5
rpc_server.py
drip_planner2/src/rpc_server.py
+6
-4
tosca.py
drip_planner2/src/utils/tosca.py
+107
-0
No files found.
drip_planner2/src/planner/planner.py
View file @
9551f6d6
...
@@ -2,13 +2,14 @@ import logging
...
@@ -2,13 +2,14 @@ import logging
from
toscaparser.nodetemplate
import
NodeTemplate
from
toscaparser.nodetemplate
import
NodeTemplate
from
toscaparser.tosca_template
import
ToscaTemplate
from
toscaparser.tosca_template
import
ToscaTemplate
import
networkx
as
nx
import
networkx
as
nx
from
src.utils.TOSCA_parser
import
TOSCAParser
import
operator
import
operator
from
planner.spec_service
import
*
from
planner.spec_service
import
*
from
utils.tosca
import
*
from
utils
import
tosca
as
tosca_util
class
Planner
:
class
Planner
:
node_type_key_names_to_remove
=
[
'capabilities'
,
'requirements'
,
'derived_from'
]
def
__init__
(
self
,
path
):
def
__init__
(
self
,
path
):
self
.
template
=
ToscaTemplate
(
path
)
self
.
template
=
ToscaTemplate
(
path
)
...
@@ -18,65 +19,76 @@ class Planner:
...
@@ -18,65 +19,76 @@ class Planner:
self
.
all_nodes
.
update
(
self
.
tosca_node_types
.
items
())
self
.
all_nodes
.
update
(
self
.
tosca_node_types
.
items
())
self
.
all_nodes
.
update
(
self
.
all_custom_def
.
items
())
self
.
all_nodes
.
update
(
self
.
all_custom_def
.
items
())
self
.
required_nodes
=
[]
self
.
required_nodes
=
[]
props
=
{}
props
=
{
'kb_url'
:
"https://host"
}
props
[
'kb_url'
]
=
"https://host"
self
.
spec_service
=
SpecService
(
props
)
self
.
spec_service
=
SpecService
(
props
)
# graph = self.build_graph(template.nodetemplates)
# graph = self.build_graph(template.nodetemplates)
def
set_infrastructure_specifications
(
self
):
def
add_required_nodes_to_template
(
self
,
required_nodes
):
self
.
set_vm_specifications
()
for
req_node
in
required_nodes
:
node_template
=
tosca_util
.
node_type_2_node_template
(
req_node
)
def
set_vm_specifications
(
self
):
self
.
template
.
nodetemplates
.
append
(
node_template
)
for
node
in
self
.
template
.
nodetemplates
:
return
self
.
template
if
node
.
type
==
'tosca.nodes.ARTICONF.VM.Compute'
:
props
=
{}
def
set_infrastructure_specifications
(
self
,
required_nodes
):
username_prop
=
node
.
get_property_value
(
'user_name'
)
required_nodes
=
self
.
set_vm_specifications
(
required_nodes
)
vm_username_val
=
self
.
spec_service
.
get_vm_username
()
required_nodes
=
self
.
set_topology_specifications
(
required_nodes
)
return
required_nodes
props
[
'properties'
]
=
self
.
set_prop
(
prop_key
,
prop_value
)
if
vm_username_val
:
def
set_vm_specifications
(
self
,
required_nodes
):
props
[
'properties'
]
=
{
'user_name'
:
vm_username_val
}
for
node
in
required_nodes
:
else
:
node_type_name
=
tosca_util
.
get_node_type_name
(
node
)
if
username_prop
[
'required'
]
==
'true'
and
username_prop
[
'default'
]:
if
node_type_name
==
'tosca.nodes.ARTICONF.VM.Compute'
:
vm_username_val
=
username_prop
[
'default'
]
node_template_props
=
{
'properties'
:
{}}
props
[
'properties'
]
=
{
'user_name'
:
vm_username_val
}
node_properties
=
tosca_util
.
get_node_properties
(
node
)
for
node_type_prop_key
in
node_properties
:
node
.
_properties
=
props
node_template_prop
=
self
.
get_node_template_property
(
node_type_prop_key
,
logging
.
info
(
str
(
node
.
_properties
))
node_properties
[
node_type_prop_key
])
# for prop in node.get_properties_objects():
node_template_props
[
'properties'
][
node_type_prop_key
]
=
node_template_prop
# logging.info(prop.name + ' : ' + str(prop.value))
node
=
tosca_util
.
set_node_properties
(
node
,
node_template_props
)
logging
.
info
(
'node: '
+
node_type_name
+
' properties: '
+
str
(
node_template_props
))
def
set_prop
(
self
,
prop_key
,
prop_value
):
return
required_nodes
def
get_node_template_property
(
self
,
prop_key
,
node_prop_dict
):
prop_value
=
self
.
spec_service
.
get_property
(
prop_key
)
if
prop_value
:
return
{
prop_key
:
node_prop_dict
}
else
:
if
'required'
in
node_prop_dict
and
'default'
in
node_prop_dict
:
return
node_prop_dict
[
'default'
]
if
'constraints'
in
node_prop_dict
:
constraints
=
node_prop_dict
[
'constraints'
]
for
constraint
in
constraints
:
if
next
(
iter
(
constraint
))
==
'greater_or_equal'
:
return
constraint
[
next
(
iter
(
constraint
))]
return
None
# Resolve requirements. Go over all nodes and recursively resolve requirements till node has no requirements
# Resolve requirements. Go over all nodes and recursively resolve requirements till node has no requirements
# e.g. docker -> k8s -> cluster -> vm
# e.g. docker -> k8s -> cluster -> vm
def
resolve_requirements
(
self
):
def
resolve_requirements
(
self
):
for
node
in
self
.
template
.
nodetemplates
:
for
node
in
self
.
template
.
nodetemplates
:
self
.
add_required_nodes
(
node
)
self
.
add_required_nodes
(
node
)
self
.
template
.
nodetemplates
.
extend
(
self
.
required_nodes
)
return
self
.
required_nodes
def
get_tosca_template
(
self
):
tp
=
TOSCAParser
()
yaml_str
=
tp
.
tosca_template2_yaml
(
self
.
template
)
return
yaml_str
def
add_required_nodes
(
self
,
node
):
def
add_required_nodes
(
self
,
node
):
node_type
=
tosca_util
.
get_node_type_name
(
node
)
missing_requirements
=
self
.
get_missing_requirements
(
node
)
missing_requirements
=
self
.
get_missing_requirements
(
node
)
if
not
missing_requirements
:
if
not
missing_requirements
:
logging
.
debug
(
'Node: '
+
node
.
type
+
' has no requirements'
)
logging
.
debug
(
'Node: '
+
node
_
type
+
' has no requirements'
)
return
return
matching_node
=
self
.
find_best_node
(
missing_requirements
)
matching_node
=
self
.
find_best_node
(
missing_requirements
)
# Only add node that is not in node_templates
# Only add node that is not in node_templates
matching_node_type_name
=
next
(
iter
(
matching_node
))
matching_node_type_name
=
next
(
iter
(
matching_node
))
capable_node_template
=
self
.
node_type_2_node_template
(
matching_node
)
# capable_node_template = self.node_type_2_node_template(matching_node)
if
not
self
.
contains_node_type
(
self
.
required_nodes
,
matching_node_type_name
):
if
not
tosca_util
.
contains_node_type
(
self
.
required_nodes
,
matching_node_type_name
):
node
=
self
.
add_missing_requirements
(
node
,
missing_requirements
,
capable_node_template
.
name
)
matching_node_type_name
=
next
(
iter
(
matching_node
))
logging
.
info
(
'Adding: '
+
str
(
capable_node_template
.
type
))
node
=
self
.
add_missing_requirements
(
node
,
missing_requirements
,
matching_node_type_name
)
self
.
required_nodes
.
append
(
capable_node_template
)
logging
.
info
(
'Adding: '
+
str
(
matching_node_type_name
))
self
.
required_nodes
.
append
(
matching_node
)
# Find matching nodes for the new node's requirements
# Find matching nodes for the new node's requirements
self
.
add_required_nodes
(
capable_node_templat
e
)
self
.
add_required_nodes
(
matching_nod
e
)
def
build_graph
(
self
,
nodetemplates
):
def
build_graph
(
self
,
nodetemplates
):
graph
=
nx
.
Graph
()
graph
=
nx
.
Graph
()
...
@@ -99,33 +111,39 @@ class Planner:
...
@@ -99,33 +111,39 @@ class Planner:
return
graph
return
graph
def
get_missing_requirements
(
self
,
node
):
def
get_missing_requirements
(
self
,
node
):
logging
.
debug
(
'Looking for requirements for node: '
+
node
.
type
)
node_type_name
=
tosca_util
.
get_node_type_name
(
node
)
def_type
=
self
.
all_nodes
[
node
.
type
]
node_requirements
=
tosca_util
.
get_node_requirements
(
node
)
parent_type_requirements
=
tosca_util
.
get_parent_type_requirements
(
node
,
self
.
all_nodes
)
logging
.
debug
(
'Looking for requirements for node: '
+
node_type_name
)
def_type
=
self
.
all_nodes
[
node_type_name
]
def_requirements
=
[]
def_requirements
=
[]
if
'requirements'
in
def_type
.
keys
():
if
'requirements'
in
def_type
.
keys
():
def_requirements
=
def_type
[
'requirements'
]
def_requirements
=
def_type
[
'requirements'
]
logging
.
debug
(
'Found requirements: '
+
str
(
def_requirements
)
+
' for node: '
+
node
.
typ
e
)
logging
.
debug
(
'Found requirements: '
+
str
(
def_requirements
)
+
' for node: '
+
node
_type_nam
e
)
missing_requirements
=
[]
missing_requirements
=
[]
if
not
node
.
requirements
:
if
not
node_requirements
:
missing_requirements
=
def_requirements
missing_requirements
=
def_requirements
elif
def_requirements
:
elif
def_requirements
:
for
def_requirement
in
def_requirements
:
for
def_requirement
in
def_requirements
:
for
key
in
def_requirement
:
for
key
in
def_requirement
:
for
node_req
in
node
.
requirements
:
for
node_req
in
node
_
requirements
:
if
key
not
in
node_req
:
if
key
not
in
node_req
:
req_name
=
next
(
iter
(
def_requirement
))
req_name
=
next
(
iter
(
def_requirement
))
def_requirement
[
req_name
][
'node'
]
=
None
def_requirement
[
req_name
][
'node'
]
=
None
missing_requirements
.
append
(
def_requirement
)
missing_requirements
.
append
(
def_requirement
)
# Make sure we have the definition. Otherwise we get an error in the recursion
# Make sure we have the definition. Otherwise we get an error in the recursion
if
'derived_from'
in
def_type
.
keys
()
and
not
def_type
[
'derived_from'
]
in
node
.
custom_def
.
keys
():
# if 'derived_from' in def_type.keys() and not def_type['derived_from'] in
custom_def.keys():
node
.
custom_def
[
def_type
[
'derived_from'
]]
=
self
.
all_custom_def
[
def_type
[
'derived_from'
]
]
# node.custom_def[def_type['derived_from']] = custom_def['derived_from'
]
parent_type
=
tosca_util
.
get_node_type_name
(
node
)
if
node
.
parent_type
and
node
.
parent_type
.
requirements
:
if
parent_type
and
parent_type_
requirements
:
logging
.
debug
(
logging
.
debug
(
' Adding to : '
+
str
(
node
.
name
)
+
' parent requirements from: '
+
str
(
node
.
parent_type
.
type
))
' Adding to : '
+
str
(
node
_type_name
)
+
' parent requirements from: '
+
str
(
parent_
type
))
missing_requirements
=
missing_requirements
+
node
.
parent_type
.
requirements
missing_requirements
=
missing_requirements
+
parent_type_
requirements
logging
.
debug
(
' missing_requirements: '
+
str
(
missing_requirements
))
logging
.
debug
(
' missing_requirements: '
+
str
(
missing_requirements
))
return
missing_requirements
return
missing_requirements
...
@@ -148,39 +166,11 @@ class Planner:
...
@@ -148,39 +166,11 @@ class Planner:
candidate_nodes
.
update
(
candidate_child_nodes
)
candidate_nodes
.
update
(
candidate_child_nodes
)
capable_nodes
=
{}
capable_nodes
=
{}
# Only return the nodes that have interfaces. This means that they are not "abstract"
# Only return the nodes that have interfaces. This means that they are not "abstract"
nodes_type_names_with_interface
=
self
.
get_node_types_with_interface
(
candidate_nodes
)
nodes_type_names_with_interface
=
tosca_util
.
get_node_types_with_interface
(
candidate_nodes
)
for
type_name
in
nodes_type_names_with_interface
:
for
type_name
in
nodes_type_names_with_interface
:
capable_nodes
[
type_name
]
=
candidate_nodes
[
type_name
]
capable_nodes
[
type_name
]
=
candidate_nodes
[
type_name
]
return
capable_nodes
return
capable_nodes
def
contains_node_type
(
self
,
node_types_list
,
node_type_name
):
if
node_types_list
is
None
:
return
False
for
node_type
in
node_types_list
:
if
isinstance
(
node_type
,
NodeTemplate
):
type_name
=
node_type
.
type
elif
isinstance
(
node_type
,
dict
):
type_name
=
next
(
iter
(
node_type
))
if
type_name
==
node_type_name
:
return
True
return
False
def
node_type_2_node_template
(
self
,
node_type
):
nodetemplate_dict
=
{}
type_name
=
next
(
iter
(
node_type
))
node_type_array
=
type_name
.
split
(
"."
)
name
=
node_type_array
[
len
(
node_type_array
)
-
1
]
.
lower
()
nodetemplate_dict
[
name
]
=
node_type
[
next
(
iter
(
node_type
))]
.
copy
()
nodetemplate_dict
[
name
][
'type'
]
=
type_name
for
name_to_remove
in
self
.
node_type_key_names_to_remove
:
if
name_to_remove
in
nodetemplate_dict
[
name
]:
nodetemplate_dict
[
name
]
.
pop
(
name_to_remove
)
if
'type'
in
node_type
[
next
(
iter
(
node_type
))]:
node_type
[
next
(
iter
(
node_type
))]
.
pop
(
'type'
)
return
NodeTemplate
(
name
,
nodetemplate_dict
,
node_type
)
def
find_best_node
(
self
,
missing_requirements
):
def
find_best_node
(
self
,
missing_requirements
):
matching_nodes
=
{}
matching_nodes
=
{}
number_of_matching_requirement
=
{}
number_of_matching_requirement
=
{}
...
@@ -226,15 +216,25 @@ class Planner:
...
@@ -226,15 +216,25 @@ class Planner:
child_nodes
[
tosca_node_type
]
=
self
.
all_nodes
[
tosca_node_type
]
child_nodes
[
tosca_node_type
]
=
self
.
all_nodes
[
tosca_node_type
]
return
child_nodes
return
child_nodes
def
get_node_types_with_interface
(
self
,
nodes
):
node_types_with_interface
=
[]
for
node_name
in
nodes
:
if
'interfaces'
in
nodes
[
node_name
]
.
keys
()
and
'tosca.nodes.Root'
!=
node_name
:
node_types_with_interface
.
append
(
node_name
)
return
node_types_with_interface
def
add_missing_requirements
(
self
,
node
,
missing_requirements
,
capable_node_name
):
def
add_missing_requirements
(
self
,
node
,
missing_requirements
,
capable_node_name
):
for
req
in
missing_requirements
:
for
req
in
missing_requirements
:
req
[
next
(
iter
(
req
))][
'node'
]
=
capable_node_name
req
[
next
(
iter
(
req
))][
'node'
]
=
capable_node_name
node
.
requirements
.
append
(
req
)
if
isinstance
(
node
,
NodeTemplate
):
contains_requirement
=
False
for
node_requirement
in
node
.
requirements
:
if
node_requirement
==
req
:
contains_requirement
=
True
break
if
not
contains_requirement
:
node
.
requirements
.
append
(
req
)
elif
isinstance
(
node
,
dict
):
type_name
=
next
(
iter
(
node
))
node_requirements
=
node
[
type_name
][
'requirements'
]
contains_requirement
=
False
for
node_requirement
in
node_requirements
:
if
node_requirement
==
req
:
contains_requirement
=
True
break
if
not
contains_requirement
:
node
[
type_name
][
'requirements'
]
.
append
(
req
)
return
node
return
node
drip_planner2/src/planner/spec_service.py
View file @
9551f6d6
class
SpecService
:
class
SpecService
:
def
__init__
(
self
,
props
):
def
__init__
(
self
,
conf
):
self
.
properties
=
props
self
.
configuration
=
conf
def
get_vm_username
(
self
):
def
get_property
(
self
,
prop_key
):
return
"vm_user"
return
None
\ No newline at end of file
drip_planner2/src/rpc_server.py
View file @
9551f6d6
...
@@ -15,6 +15,7 @@ import tempfile
...
@@ -15,6 +15,7 @@ import tempfile
import
time
import
time
import
logging
import
logging
import
base64
import
base64
from
utils
import
tosca
as
tosca_util
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
# if not getattr(logger, 'handler_set', None):
# if not getattr(logger, 'handler_set', None):
...
@@ -127,10 +128,11 @@ if __name__ == "__main__":
...
@@ -127,10 +128,11 @@ if __name__ == "__main__":
tosca_file_path
=
"../../TOSCA/application_example.yaml"
tosca_file_path
=
"../../TOSCA/application_example.yaml"
# planner = BasicPlanner(tosca_file_path)
# planner = BasicPlanner(tosca_file_path)
planner
=
Planner
(
tosca_file_path
)
planner
=
Planner
(
tosca_file_path
)
planner
.
resolve_requirements
()
required_nodes
=
planner
.
resolve_requirements
()
planner
.
set_infrastructure_specifications
()
required_nodes
=
planner
.
set_infrastructure_specifications
(
required_nodes
)
template
=
planner
.
get_tosca_template
()
planner
.
add_required_nodes_to_template
(
required_nodes
)
# logger.info("template ----: \n" + template)
template
=
tosca_util
.
get_tosca_template_as_yml
(
planner
.
template
)
logger
.
info
(
"template ----:
\n
"
+
template
)
else
:
else
:
logger
.
info
(
"Input args: "
+
sys
.
argv
[
0
]
+
' '
+
sys
.
argv
[
1
]
+
' '
+
sys
.
argv
[
2
])
logger
.
info
(
"Input args: "
+
sys
.
argv
[
0
]
+
' '
+
sys
.
argv
[
1
]
+
' '
+
sys
.
argv
[
2
])
channel
=
init_chanel
(
sys
.
argv
)
channel
=
init_chanel
(
sys
.
argv
)
...
...
drip_planner2/src/utils/tosca.py
0 → 100644
View file @
9551f6d6
from
toscaparser.nodetemplate
import
NodeTemplate
from
utils.TOSCA_parser
import
TOSCAParser
node_type_key_names_to_remove
=
[
'capabilities'
,
'requirements'
,
'derived_from'
]
def
get_node_type_name
(
node
):
if
isinstance
(
node
,
NodeTemplate
):
node_type
=
node
.
type
elif
isinstance
(
node
,
dict
):
node_type
=
next
(
iter
(
node
))
return
node_type
def
get_node_requirements
(
node
):
if
isinstance
(
node
,
NodeTemplate
):
node_requirements
=
node
.
requirements
elif
isinstance
(
node
,
dict
):
node_type_name
=
get_node_type_name
(
node
)
if
'requirements'
not
in
node
[
node_type_name
]:
node
[
node_type_name
][
'requirements'
]
=
{}
node_requirements
=
node
[
node_type_name
][
'requirements'
]
return
node_requirements
def
get_parent_type
(
node
):
if
isinstance
(
node
,
NodeTemplate
):
parent_type
=
node
.
parent_type
elif
isinstance
(
node
,
dict
):
parent_type
=
node
[
node_type_name
][
'derived_from'
]
return
parent_type
def
get_node_type_requirements
(
type_name
,
all_nodes
):
def_type
=
all_nodes
[
type_name
]
if
'requirements'
in
def_type
.
keys
():
return
def_type
[
'requirements'
]
return
None
def
get_parent_type_requirements
(
node
,
all_nodes
):
if
isinstance
(
node
,
NodeTemplate
):
if
node
.
parent_type
and
node
.
parent_type
.
requirements
:
parent_type_requirements
=
node
.
parent_type
.
requirements
else
:
parent_type_requirements
=
{}
elif
isinstance
(
node
,
dict
):
node_type_name
=
get_node_type_name
(
node
)
parent_type_requirements
=
get_node_type_requirements
(
node_type_name
,
all_nodes
)
return
parent_type_requirements
def
get_node_types_with_interface
(
nodes
):
node_types_with_interface
=
[]
for
node_name
in
nodes
:
if
'interfaces'
in
nodes
[
node_name
]
.
keys
()
and
'tosca.nodes.Root'
!=
node_name
:
node_types_with_interface
.
append
(
node_name
)
return
node_types_with_interface
def
node_type_2_node_template
(
node_type
):
nodetemplate_dict
=
{}
type_name
=
next
(
iter
(
node_type
))
node_type_array
=
type_name
.
split
(
"."
)
name
=
node_type_array
[
len
(
node_type_array
)
-
1
]
.
lower
()
nodetemplate_dict
[
name
]
=
node_type
[
next
(
iter
(
node_type
))]
.
copy
()
nodetemplate_dict
[
name
][
'type'
]
=
type_name
for
name_to_remove
in
node_type_key_names_to_remove
:
if
name_to_remove
in
nodetemplate_dict
[
name
]:
nodetemplate_dict
[
name
]
.
pop
(
name_to_remove
)
if
'type'
in
node_type
[
next
(
iter
(
node_type
))]:
node_type
[
next
(
iter
(
node_type
))]
.
pop
(
'type'
)
return
NodeTemplate
(
name
,
nodetemplate_dict
,
node_type
)
def
get_tosca_template_as_yml
(
template
):
tp
=
TOSCAParser
()
yaml_str
=
tp
.
tosca_template2_yaml
(
template
)
return
yaml_str
def
contains_node_type
(
node_types_list
,
node_type_name
):
if
node_types_list
is
None
:
return
False
for
node_type
in
node_types_list
:
if
isinstance
(
node_type
,
NodeTemplate
):
type_name
=
node_type
.
type
elif
isinstance
(
node_type
,
dict
):
type_name
=
next
(
iter
(
node_type
))
if
type_name
==
node_type_name
:
return
True
return
False
def
get_node_properties
(
node
):
node_type_name
=
get_node_type_name
(
node
)
return
node
[
node_type_name
][
'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
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