Commit b8df0432 authored by Spiros Koulouzis's avatar Spiros Koulouzis

fixed policies error

parent 29a7b31f
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="462ede19-adfe-472b-975e-fefefa973fe0" name="Default Changelist" comment=""> <list default="true" id="462ede19-adfe-472b-975e-fefefa973fe0" name="Default Changelist" comment="">
<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/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$/../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$/.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>
...@@ -218,7 +220,14 @@ ...@@ -218,7 +220,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1571677538860</updated> <updated>1571677538860</updated>
</task> </task>
<option name="localTasksCounter" value="15" /> <task id="LOCAL-00015" summary="set min number of VMs based on the swarm default workers and masters">
<created>1571748060598</created>
<option name="number" value="00015" />
<option name="presentableId" value="LOCAL-00015" />
<option name="project" value="LOCAL" />
<updated>1571748060598</updated>
</task>
<option name="localTasksCounter" value="16" />
<servers /> <servers />
</component> </component>
<component name="Vcs.Log.Tabs.Properties"> <component name="Vcs.Log.Tabs.Properties">
...@@ -248,7 +257,8 @@ ...@@ -248,7 +257,8 @@
<MESSAGE value="fixed invalid type" /> <MESSAGE value="fixed invalid type" />
<MESSAGE value="added comments" /> <MESSAGE value="added comments" />
<MESSAGE value="set default properties" /> <MESSAGE value="set default properties" />
<option name="LAST_COMMIT_MESSAGE" value="set default properties" /> <MESSAGE value="set min number of VMs based on the swarm default workers and masters" />
<option name="LAST_COMMIT_MESSAGE" value="set min number of VMs based on the swarm default workers and masters" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
...@@ -260,18 +270,13 @@ ...@@ -260,18 +270,13 @@
</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>21</line> <line>22</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/rpc_server.py</url> <url>file://$PROJECT_DIR$/src/rpc_server.py</url>
<line>117</line> <line>134</line>
<option name="timeStamp" value="255" /> <option name="timeStamp" value="295" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/utils/TOSCA_parser.py</url>
<line>67</line>
<option name="timeStamp" value="256" />
</line-breakpoint> </line-breakpoint>
</breakpoints> </breakpoints>
<default-breakpoints> <default-breakpoints>
......
...@@ -61,7 +61,6 @@ class Planner: ...@@ -61,7 +61,6 @@ class Planner:
self.tosca_template.nodetemplates.append(new_spec_occurrences) self.tosca_template.nodetemplates.append(new_spec_occurrences)
return self.tosca_template 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:
...@@ -81,13 +80,15 @@ class Planner: ...@@ -81,13 +80,15 @@ class Planner:
""" Resolve requirements. Go over all nodes and recursively resolve requirements till node has no """ Resolve requirements. Go over all nodes and recursively resolve requirements till node has no
requirements e.g. docker -> k8s -> cluster -> vm """ requirements e.g. docker -> k8s -> cluster -> vm """
for node in self.tosca_template.nodetemplates: for node in self.tosca_template.nodetemplates:
logging.info('Resolving requirements for: ' + node.name)
self.add_required_nodes(node) self.add_required_nodes(node)
return self.add_required_nodes_to_template(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."""
if isinstance(node, NodeTemplate):
logging.info('Resolving requirements for: ' + node.name)
elif isinstance(node, dict):
logging.info('Resolving requirements for: ' + str(next(iter(node))))
# Get all requirements for node. # Get all requirements for node.
all_requirements = self.get_all_requirements(node) all_requirements = self.get_all_requirements(node)
if not all_requirements: if not all_requirements:
...@@ -130,7 +131,16 @@ class Planner: ...@@ -130,7 +131,16 @@ class Planner:
if parent_type and parent_requirements: if parent_type and parent_requirements:
logging.info( logging.info(
' Adding to : ' + str(node_type_name) + ' parent requirements from: ' + str(parent_type)) ' Adding to : ' + str(node_type_name) + ' parent requirements from: ' + str(parent_type))
missing_requirements = all_requirements + parent_requirements if not all_requirements:
all_requirements += parent_requirements
else:
for all_requirement in all_requirements:
for parent_requirement in parent_requirements:
all_requirement_key = next(iter(all_requirement))
parent_requirement_key = next(iter(parent_requirement))
if all_requirement_key != parent_requirement_key and all_requirement[all_requirement_key]['capability'] != parent_requirement[parent_requirement_key]['capability']:
all_requirements.append(parent_requirement)
logging.debug(' all_requirements: ' + str(all_requirements)) logging.debug(' all_requirements: ' + str(all_requirements))
return all_requirements return all_requirements
...@@ -167,7 +177,7 @@ class Planner: ...@@ -167,7 +177,7 @@ class Planner:
number_of_matching_requirement = {} number_of_matching_requirement = {}
# Loop requirements to find nodes per requirement # Loop requirements to find nodes per requirement
for req in all_requirements: for req in all_requirements:
if 'capability' in req[next(iter(req))]: if 'capability' in req[next(iter(req))]:
capability = req[next(iter(req))]['capability'] capability = req[next(iter(req))]['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 # Find all nodes in the definitions that have the capability: capability
...@@ -221,6 +231,8 @@ class Planner: ...@@ -221,6 +231,8 @@ class Planner:
node.requirements.append(req) node.requirements.append(req)
elif isinstance(node, dict): elif isinstance(node, dict):
type_name = next(iter(node)) type_name = next(iter(node))
if 'requirements' not in node[type_name]:
node[type_name]['requirements'] = []
node_requirements = node[type_name]['requirements'] node_requirements = node[type_name]['requirements']
contains_requirement = False contains_requirement = False
for node_requirement in node_requirements: for node_requirement in node_requirements:
......
...@@ -22,9 +22,9 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -22,9 +22,9 @@ class SimpleAnalyzer(SpecificationAnalyzer):
self.tosca_template.nodetemplates, self.all_node_types, self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def) self.all_custom_def)
min_num_of_vm = orchestrator_nodes[0].get_property_value('masters_num') masters_num = orchestrator_nodes[0].get_property_value('masters_num')
min_num_of_vm += orchestrator_nodes[0].get_property_value('workers_num') workers_num = orchestrator_nodes[0].get_property_value('workers_num')
min_num_of_vm = masters_num + workers_num
topology_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.VM.topology', topology_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.VM.topology',
self.tosca_template.nodetemplates, self.all_node_types, self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def) self.all_custom_def)
...@@ -37,25 +37,45 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -37,25 +37,45 @@ class SimpleAnalyzer(SpecificationAnalyzer):
vm_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.VM.Compute', vm_nodes = tosca_util.get_nodes_by_type('tosca.nodes.ARTICONF.VM.Compute',
self.tosca_template.nodetemplates, self.all_node_types, self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def) self.all_custom_def)
if vm_nodes:
for i in range(len(vm_nodes), min_num_of_vm): for i in range(len(vm_nodes), masters_num):
old_vm_name = vm_nodes[0].name old_vm_name = vm_nodes[0].name
new_vm = copy.deepcopy(vm_nodes[0]) new_vm = copy.deepcopy(vm_nodes[0])
new_vm_name = new_vm.name + '_' + str(i) new_vm_name = new_vm.name + '_' + str(i)
new_vm.name = new_vm_name new_vm.name = new_vm_name
templates = new_vm.templates.pop(old_vm_name) templates = new_vm.templates.pop(old_vm_name)
new_vm.templates[new_vm_name] = templates new_vm.templates[new_vm_name] = templates
return_nodes.append(new_vm) return_nodes.append(new_vm)
for requirement in topology_nodes[0].requirements: for requirement in topology_nodes[0].requirements:
requirement_key = next(iter(requirement)) requirement_key = next(iter(requirement))
requirement_value = requirement[requirement_key] requirement_value = requirement[requirement_key]
if requirement_value['capability'] == 'tosca.capabilities.ARTICONF.VM': if requirement_value['capability'] == 'tosca.capabilities.ARTICONF.VM':
new_requirement = copy.deepcopy(requirement) new_requirement = copy.deepcopy(requirement)
new_requirement[requirement_key]['node'] = new_vm.name new_requirement[requirement_key]['node'] = new_vm.name
topology_nodes[0].requirements.append(new_requirement) topology_nodes[0].requirements.append(new_requirement)
return_nodes.append(topology_nodes[0]) return_nodes.append(topology_nodes[0])
break break
for i in range(len(vm_nodes), workers_num + 1):
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
new_vm.templates[next(iter(new_vm.templates))]['properties']['role'] = "worker"
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 return return_nodes
...@@ -76,7 +96,6 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -76,7 +96,6 @@ class SimpleAnalyzer(SpecificationAnalyzer):
for policy in self.tosca_template.policies: for policy in self.tosca_template.policies:
for target in policy.targets: for target in policy.targets:
for leaf in self.leaf_nodes: for leaf in self.leaf_nodes:
logging.info('From: ' + target + ' to: ' + str(leaf))
for affected_node_name in (nx.shortest_path(self.g, source=target, target=leaf)): for affected_node_name in (nx.shortest_path(self.g, source=target, target=leaf)):
if affected_node_name not in nodes_to_implement_policies: if affected_node_name not in nodes_to_implement_policies:
policy_list = [] policy_list = []
...@@ -105,16 +124,15 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -105,16 +124,15 @@ class SimpleAnalyzer(SpecificationAnalyzer):
for default_property in default_properties: for default_property in default_properties:
affected_node.get_properties_objects().append(default_property) affected_node.get_properties_objects().append(default_property)
if 'properties' not in affected_node.templates[next(iter(affected_node.templates))]: for prop_name in affected_node.templates[next(iter(affected_node.templates))]['properties']:
affected_node.templates[next(iter(affected_node.templates))]['properties'] = default_properties if 'required' not in affected_node.templates[next(iter(affected_node.templates))]['properties'][
else: prop_name] and 'type' not in \
for prop_name in affected_node.templates[next(iter(affected_node.templates))]['properties']: affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name]:
if 'required' in affected_node.templates[next(iter(affected_node.templates))]['properties'][ default_properties[prop_name] = \
prop_name] and 'type' in \ affected_node.templates[next(iter(affected_node.templates))]['properties'][(prop_name)]
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'] = default_properties
affected_node.templates[next(iter(affected_node.templates))]['properties'][prop_name] = None
affected_node.templates[next(iter(affected_node.templates))]['properties'].update(default_properties)
return affected_node return affected_node
else: else:
return None return None
...@@ -134,6 +152,7 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -134,6 +152,7 @@ class SimpleAnalyzer(SpecificationAnalyzer):
def get_defult_value(self, node_property): def get_defult_value(self, node_property):
if isinstance(node_property.value, if isinstance(node_property.value,
dict) and 'required' in node_property.value and 'type' in node_property.value: dict) and 'required' in node_property.value and 'type' in node_property.value:
logging.info('node property: ' + str(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:
...@@ -151,7 +170,6 @@ class SimpleAnalyzer(SpecificationAnalyzer): ...@@ -151,7 +170,6 @@ class SimpleAnalyzer(SpecificationAnalyzer):
else: else:
default_prop = str(constraint[constraint_key]) default_prop = str(constraint[constraint_key])
name = node_property.name name = node_property.name
node_property = None
node_property = {name: default_prop} node_property = {name: default_prop}
return node_property return node_property
return None return None
...@@ -36,10 +36,13 @@ class SpecificationAnalyzer(metaclass=ABCMeta): ...@@ -36,10 +36,13 @@ class SpecificationAnalyzer(metaclass=ABCMeta):
for req in node.requirements: for req in node.requirements:
req_name = next(iter(req)) req_name = next(iter(req))
req_node_name = req[req_name]['node'] req_node_name = req[req_name]['node']
if 'type' in req[req_name]['relationship']: if 'relationship' in req[req_name] and 'type' in req[req_name]['relationship']:
relationship_type = req[req_name]['relationship']['type'] relationship_type = req[req_name]['relationship']['type']
else: else:
relationship_type = req[req_name]['relationship'] if 'relationship' not in req[req_name]:
relationship_type = 'tosca.relationships.DependsOn'
else:
relationship_type = req[req_name]['relationship']
graph.add_edge(node.name, req_node_name, relationship=relationship_type) graph.add_edge(node.name, req_node_name, relationship=relationship_type)
nx.draw(graph, with_labels=True) nx.draw(graph, with_labels=True)
......
...@@ -109,14 +109,30 @@ def handle_delivery(message): ...@@ -109,14 +109,30 @@ def handle_delivery(message):
if __name__ == "__main__": if __name__ == "__main__":
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
if sys.argv[1] == "test_local": if sys.argv[1] == "test_local":
tosca_file_path = "../../TOSCA/application_example_updated.yaml" tosca_path = "../../TOSCA/"
tosca_file_path = tosca_path+'/application_example_updated.yaml'
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)
tosca_template = test_planner.resolve_requirements() tosca_template = test_planner.resolve_requirements()
tosca_template = test_planner.set_infrastructure_specifications() tosca_template = 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_dictionary(tosca_template)
logger.info("template ----: \n" + template) logger.info("template ----: \n" + yaml.dump(template))
try:
tosca_folder_path = os.path.join(tempfile.gettempdir(), tosca_path)
except NameError:
import sys
tosca_folder_path = os.path.dirname(os.path.abspath(sys.argv[0])) + os.path.join(tempfile.gettempdir(),
tosca_path)
tosca_file_name = 'tosca_template'
input_tosca_file_path = tosca_path+'/application_example_output.yaml'
with open(input_tosca_file_path, 'w') as outfile:
outfile.write(yaml.dump(template))
ToscaTemplate(input_tosca_file_path)
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)
......
...@@ -9,6 +9,7 @@ from utils.TOSCA_parser import TOSCAParser ...@@ -9,6 +9,7 @@ from utils.TOSCA_parser import TOSCAParser
import yaml import yaml
import logging import logging
node_type_key_names_to_remove = ['capabilities', 'derived_from'] node_type_key_names_to_remove = ['capabilities', 'derived_from']
...@@ -76,7 +77,7 @@ def get_ancestors_requirements(node, all_nodes, all_custom_def, parent_requireme ...@@ -76,7 +77,7 @@ def get_ancestors_requirements(node, all_nodes, all_custom_def, parent_requireme
elif isinstance(node, dict): elif isinstance(node, dict):
node_type_name = get_node_type_name(node) node_type_name = get_node_type_name(node)
node_template = node_type_2_node_template({'name': all_nodes[node_type_name]}, all_custom_def) node_template = node_type_2_node_template({'name': all_nodes[node_type_name]}, all_custom_def)
get_ancestors_requirements(node_template, all_nodes, all_custom_def, parent_requirements) return get_ancestors_requirements(node_template, all_nodes, all_custom_def, parent_requirements)
return parent_requirements return parent_requirements
...@@ -117,7 +118,7 @@ def node_type_2_node_template(node_type, all_custom_def): ...@@ -117,7 +118,7 @@ def node_type_2_node_template(node_type, all_custom_def):
return node_template return node_template
def get_tosca_template_2_topology_template(template): def get_tosca_template_2_topology_template_dictionary(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)
...@@ -128,9 +129,10 @@ def get_tosca_template_2_topology_template(template): ...@@ -128,9 +129,10 @@ def get_tosca_template_2_topology_template(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 = []
for policy in template.policies: for policy in template.policies:
policies_list.append(policy.entity_tpl) policy_dict = {policy.name: policy.entity_tpl}
policies_list.append(policy_dict)
tosca_template_dict['topology_template']['policies'] = policies_list tosca_template_dict['topology_template']['policies'] = policies_list
return yaml.dump(tosca_template_dict) return tosca_template_dict
def contains_node_type(node_types_list, node_type_name): def contains_node_type(node_types_list, node_type_name):
......
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