Commit 29a7b31f authored by Spiros Koulouzis's avatar Spiros Koulouzis

set min number of VMs based on the swarm default workers and masters

parent 8760f131
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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/planner/planner.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/planner/planner.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/planner/simple_spec_alayzer.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/planner/simple_spec_alayzer.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/planner/simple_spec_alayzer.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/planner/simple_spec_alayzer.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/planner/specification_analyzer.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/planner/specification_analyzer.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/rpc_server.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/rpc_server.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils/tosca.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/tosca.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/utils/tosca.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/tosca.py" afterDir="false" />
</list> </list>
...@@ -212,7 +211,14 @@ ...@@ -212,7 +211,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1571415019998</updated> <updated>1571415019998</updated>
</task> </task>
<option name="localTasksCounter" value="14" /> <task id="LOCAL-00014" summary="set default properties">
<created>1571677538860</created>
<option name="number" value="00014" />
<option name="presentableId" value="LOCAL-00014" />
<option name="project" value="LOCAL" />
<updated>1571677538860</updated>
</task>
<option name="localTasksCounter" value="15" />
<servers /> <servers />
</component> </component>
<component name="Vcs.Log.Tabs.Properties"> <component name="Vcs.Log.Tabs.Properties">
...@@ -241,7 +247,8 @@ ...@@ -241,7 +247,8 @@
<MESSAGE value="added libs in setup" /> <MESSAGE value="added libs in setup" />
<MESSAGE value="fixed invalid type" /> <MESSAGE value="fixed invalid type" />
<MESSAGE value="added comments" /> <MESSAGE value="added comments" />
<option name="LAST_COMMIT_MESSAGE" value="added comments" /> <MESSAGE value="set default properties" />
<option name="LAST_COMMIT_MESSAGE" value="set default properties" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
...@@ -253,28 +260,18 @@ ...@@ -253,28 +260,18 @@
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> <line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/utils/tosca.py</url> <url>file://$PROJECT_DIR$/src/utils/tosca.py</url>
<line>20</line> <line>21</line>
<option name="timeStamp" value="128" /> <option name="timeStamp" value="128" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> <line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/planner/planner.py</url> <url>file://$PROJECT_DIR$/src/rpc_server.py</url>
<line>173</line> <line>117</line>
<option name="timeStamp" value="218" /> <option name="timeStamp" value="255" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> <line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/planner/simple_spec_alayzer.py</url> <url>file://$PROJECT_DIR$/src/utils/TOSCA_parser.py</url>
<line>67</line> <line>67</line>
<option name="timeStamp" value="293" /> <option name="timeStamp" value="256" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/planner/simple_spec_alayzer.py</url>
<line>68</line>
<option name="timeStamp" value="294" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/planner/simple_spec_alayzer.py</url>
<line>88</line>
<option name="timeStamp" value="295" />
</line-breakpoint> </line-breakpoint>
</breakpoints> </breakpoints>
<default-breakpoints> <default-breakpoints>
......
...@@ -38,13 +38,30 @@ class Planner: ...@@ -38,13 +38,30 @@ class Planner:
# Get root performance, version requirements and set specs to required node # Get root performance, version requirements and set specs to required node
specification_analyzer = SimpleAnalyzer(self.tosca_template) specification_analyzer = SimpleAnalyzer(self.tosca_template)
nodes_with_new_specifications = specification_analyzer.set_node_specifications() nodes_with_new_specifications = specification_analyzer.set_node_specifications()
for new_spec_node in nodes_with_new_specifications: for new_spec_node in nodes_with_new_specifications:
logging.info('new_spec_node.name : ' + new_spec_node.name)
for index, node_in_temple in enumerate(self.tosca_template.nodetemplates): for index, node_in_temple in enumerate(self.tosca_template.nodetemplates):
if new_spec_node.name == node_in_temple.name: if new_spec_node.name == node_in_temple.name:
self.tosca_template.nodetemplates[index] = new_spec_node self.tosca_template.nodetemplates[index] = new_spec_node
break
specification_analyzer = SimpleAnalyzer(self.tosca_template)
nodes_with_new_relationship_occurrences = specification_analyzer.set_relationship_occurrences() nodes_with_new_relationship_occurrences = specification_analyzer.set_relationship_occurrences()
added_node_names = []
for new_spec_occurrences in nodes_with_new_relationship_occurrences:
for index, node_in_temple in enumerate(self.tosca_template.nodetemplates):
if new_spec_occurrences.name == node_in_temple.name:
added_node_names.append(new_spec_occurrences.name)
self.tosca_template.nodetemplates[index] = new_spec_occurrences
break
for new_spec_occurrences in nodes_with_new_relationship_occurrences:
if new_spec_occurrences.name not in added_node_names:
self.tosca_template.nodetemplates.append(new_spec_occurrences)
return self.tosca_template
def get_node_template_property(self, prop_key, node_prop_dict): def get_node_template_property(self, prop_key, node_prop_dict):
prop_value = self.spec_service.get_property(prop_key) prop_value = self.spec_service.get_property(prop_key)
if prop_value: if prop_value:
...@@ -66,7 +83,7 @@ class Planner: ...@@ -66,7 +83,7 @@ class Planner:
for node in self.tosca_template.nodetemplates: for node in self.tosca_template.nodetemplates:
logging.info('Resolving requirements for: ' + node.name) logging.info('Resolving requirements for: ' + node.name)
self.add_required_nodes(node) self.add_required_nodes(node)
return self.required_nodes return self.add_required_nodes_to_template(self.required_nodes)
def add_required_nodes(self, node): def add_required_nodes(self, node):
"""Adds the required nodes in self.required_nodes for an input node.""" """Adds the required nodes in self.required_nodes for an input node."""
......
import copy
from toscaparser.nodetemplate import NodeTemplate from toscaparser.nodetemplate import NodeTemplate
from toscaparser.properties import Property from toscaparser.properties import Property
...@@ -13,7 +15,49 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -13,7 +15,49 @@ class SimpleAnalyzer(SpecificationAnalyzer):
super(SimpleAnalyzer, self).__init__(tosca_template) super(SimpleAnalyzer, self).__init__(tosca_template)
def set_relationship_occurrences(self): def set_relationship_occurrences(self):
return None return_nodes = []
# nodes_with_occurrences_in_requirements = tosca_util.get_nodes_with_occurrences_in_requirements(
# self.tosca_template.nodetemplates)
orchestrator_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.Orchestrator',
self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def)
min_num_of_vm = orchestrator_nodes[0].get_property_value('masters_num')
min_num_of_vm += orchestrator_nodes[0].get_property_value('workers_num')
topology_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.VM.topology',
self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def)
# for requirement in topology_nodes[0].requirements:
# requirement_dict = requirement[next(iter(requirement))]
# if requirement_dict['capability'] == 'tosca.capabilities.ARTICONF.VM':
# requirement_dict['occurrences'] = min_num_of_vm
vm_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.VM.Compute',
self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def)
for i in range(len(vm_nodes), min_num_of_vm):
old_vm_name = vm_nodes[0].name
new_vm = copy.deepcopy(vm_nodes[0])
new_vm_name = new_vm.name + '_' + str(i)
new_vm.name = new_vm_name
templates = new_vm.templates.pop(old_vm_name)
new_vm.templates[new_vm_name] = templates
return_nodes.append(new_vm)
for requirement in topology_nodes[0].requirements:
requirement_key = next(iter(requirement))
requirement_value = requirement[requirement_key]
if requirement_value['capability'] == 'tosca.capabilities.ARTICONF.VM':
new_requirement = copy.deepcopy(requirement)
new_requirement[requirement_key]['node'] = new_vm.name
topology_nodes[0].requirements.append(new_requirement)
return_nodes.append(topology_nodes[0])
break
return return_nodes
def set_node_specifications(self): def set_node_specifications(self):
nodes_to_implement_policies = self.get_nodes_to_implement_policy() nodes_to_implement_policies = self.get_nodes_to_implement_policy()
...@@ -65,7 +109,9 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -65,7 +109,9 @@ class SimpleAnalyzer(SpecificationAnalyzer):
affected_node.templates[next(iter(affected_node.templates))]['properties'] = default_properties affected_node.templates[next(iter(affected_node.templates))]['properties'] = default_properties
else: else:
for prop_name in affected_node.templates[next(iter(affected_node.templates))]['properties']: for prop_name in affected_node.templates[next(iter(affected_node.templates))]['properties']:
if 'required' in affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name] and 'type' in affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name]: if 'required' in affected_node.templates[next(iter(affected_node.templates))]['properties'][
prop_name] and 'type' in \
affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name]:
# del affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name] # del affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name]
affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name] = None affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name] = None
affected_node.templates[next(iter(affected_node.templates))]['properties'].update(default_properties) affected_node.templates[next(iter(affected_node.templates))]['properties'].update(default_properties)
...@@ -86,7 +132,8 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -86,7 +132,8 @@ class SimpleAnalyzer(SpecificationAnalyzer):
return affected_node return affected_node
def get_defult_value(self, node_property): def get_defult_value(self, node_property):
if isinstance(node_property.value, dict) and 'required' in node_property.value and 'type' in node_property.value: if isinstance(node_property.value,
dict) and 'required' in node_property.value and 'type' in node_property.value:
if node_property.value['required']: if node_property.value['required']:
default_prop = {} default_prop = {}
if 'default' in node_property.value: if 'default' in node_property.value:
......
...@@ -113,10 +113,9 @@ if __name__ == "__main__": ...@@ -113,10 +113,9 @@ if __name__ == "__main__":
conf = {'url': "http://host"} conf = {'url': "http://host"}
spec_service = SpecService(conf) spec_service = SpecService(conf)
test_planner = Planner(tosca_file_path, spec_service) test_planner = Planner(tosca_file_path, spec_service)
test_planner_required_nodes = test_planner.resolve_requirements() tosca_template = test_planner.resolve_requirements()
test_planner.add_required_nodes_to_template(test_planner_required_nodes) tosca_template = test_planner.set_infrastructure_specifications()
test_planner_required_nodes = test_planner.set_infrastructure_specifications() template = tosca_util.get_tosca_template_2_topology_template(tosca_template)
template = tosca_util.get_tosca_template_2_topology_template(test_planner.tosca_template)
logger.info("template ----: \n" + 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])
......
import copy import copy
from itertools import chain from itertools import chain
from toscaparser import tosca_template
from toscaparser.elements.nodetype import NodeType from toscaparser.elements.nodetype import NodeType
from toscaparser.nodetemplate import NodeTemplate from toscaparser.nodetemplate import NodeTemplate
...@@ -12,7 +13,7 @@ node_type_key_names_to_remove = ['capabilities', 'derived_from'] ...@@ -12,7 +13,7 @@ node_type_key_names_to_remove = ['capabilities', 'derived_from']
def get_node_type_name(node): def get_node_type_name(node):
"""Returns the requirements for an input node as described in the template not in the node's definition """ """Returns the node's type name as string"""
if isinstance(node, NodeTemplate): if isinstance(node, NodeTemplate):
if node.type: if node.type:
if node.type and isinstance(node.type, str): if node.type and isinstance(node.type, str):
...@@ -49,6 +50,7 @@ def get_parent_type(node): ...@@ -49,6 +50,7 @@ def get_parent_type(node):
def get_node_type_requirements(type_name, all_nodes): def get_node_type_requirements(type_name, all_nodes):
"""Returns the requirements for an input node as described in the template not in the node's definition """
def_type = all_nodes[type_name] def_type = all_nodes[type_name]
if 'requirements' in def_type.keys(): if 'requirements' in def_type.keys():
return def_type['requirements'] return def_type['requirements']
...@@ -119,9 +121,9 @@ def get_tosca_template_2_topology_template(template): ...@@ -119,9 +121,9 @@ def get_tosca_template_2_topology_template(template):
tp = TOSCAParser() tp = TOSCAParser()
yaml_str = tp.tosca_template2_yaml(template) yaml_str = tp.tosca_template2_yaml(template)
tosca_template_dict = yaml.load(yaml_str, Loader=yaml.FullLoader) tosca_template_dict = yaml.load(yaml_str, Loader=yaml.FullLoader)
tosca_template = tosca_template_dict['tosca_template'] this_tosca_template = tosca_template_dict['tosca_template']
tosca_template_dict.pop('tosca_template') tosca_template_dict.pop('tosca_template')
tosca_template_dict['topology_template'] = tosca_template tosca_template_dict['topology_template'] = this_tosca_template
if template.policies and 'policies' not in tosca_template_dict['topology_template']: if template.policies and 'policies' not in tosca_template_dict['topology_template']:
policies_list = [] policies_list = []
...@@ -155,18 +157,25 @@ def set_node_properties(node, properties): ...@@ -155,18 +157,25 @@ def set_node_properties(node, properties):
return node return node
def get_node_by_type(node_type, all_nodes): def get_nodes_by_type(node_type, nodes, all_node_types, all_custom_def):
return all_nodes[node_type] nodes_by_type = []
for node in nodes:
if node.type == node_type:
nodes_by_type.append(node)
break
elif node_type in get_all_ancestors_types(node, all_node_types, all_custom_def):
nodes_by_type.append(node)
return nodes_by_type
def get_all_ancestors_types(child_node, all_nodes, all_custom_def, ancestors_types=None): def get_all_ancestors_types(child_node, all_node_types, all_custom_def, ancestors_types=None):
if not ancestors_types: if not ancestors_types:
ancestors_types = [get_node_type_name(child_node)] ancestors_types = [get_node_type_name(child_node)]
parent_type = get_parent_type(child_node) parent_type = get_parent_type(child_node)
if parent_type: if parent_type:
ancestors_types.append(parent_type) ancestors_types.append(parent_type)
parent_type = node_type_2_node_template({'name': all_nodes[parent_type]}, all_custom_def) parent_type = node_type_2_node_template({'name': all_node_types[parent_type]}, all_custom_def)
get_all_ancestors_types(parent_type, all_nodes, all_custom_def, ancestors_types) get_all_ancestors_types(parent_type, all_node_types, all_custom_def, ancestors_types)
return ancestors_types return ancestors_types
...@@ -191,3 +200,14 @@ def get_all_ancestors_properties(node, all_nodes, all_custom_def, ancestors_prop ...@@ -191,3 +200,14 @@ def get_all_ancestors_properties(node, all_nodes, all_custom_def, ancestors_prop
ancestors_properties.append(ancestor_prop) ancestors_properties.append(ancestor_prop)
return ancestors_properties return ancestors_properties
def get_nodes_with_occurrences_in_requirements(topology_nodes):
nodes_with_occurrences_in_requirement = []
for node in topology_nodes:
for requirement in node.requirements:
requirement_dict = requirement[next(iter(requirement))]
if 'occurrences' in requirement_dict:
nodes_with_occurrences_in_requirement.append(node)
break
return nodes_with_occurrences_in_requirement
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment