Commit e0127d00 authored by Spiros Koulouzis's avatar Spiros Koulouzis

create NodeTemplate from types

parent 37e7927d
...@@ -46,8 +46,15 @@ topology_template: ...@@ -46,8 +46,15 @@ topology_template:
image: image:
type: tosca.artifacts.Deployment.Image.Container.Docker type: tosca.artifacts.Deployment.Image.Container.Docker
file: mysql:5.7 file: mysql:5.7
repository: docker_hub repository: docker_hub
#guillermo_kubernetes:
#type: tosca.nodes.ARTICONF.Orchestrator.Kubernetes
#cluster:
#type: tosca.nodes.Compute
......
...@@ -46,19 +46,12 @@ node_types: ...@@ -46,19 +46,12 @@ node_types:
capabilities: capabilities:
host: host:
type: tosca.capabilities.ARTICONF.Orchestrator type: tosca.capabilities.ARTICONF.Orchestrator
occurrences: [1, 1] occurrences: [1, 1]
cap:
type: tosca.capabilities.ROOT
occurrences: [1, 1]
tosca.nodes.ARTICONF.Orchestrator.Kubernetes: tosca.nodes.ARTICONF.Orchestrator.Kubernetes:
derived_from: tosca.nodes.ARTICONF.Orchestrator derived_from: tosca.nodes.ARTICONF.Orchestrator
description: Kubernetes orchestrator description: Kubernetes orchestrator
capabilities:
cap_1:
type: tosca.capabilities.ROOT
occurrences: [1, 100]
requirements: requirements:
- host: - host:
capability: tosca.capabilities.Scalable capability: tosca.capabilities.Scalable
...@@ -66,7 +59,6 @@ node_types: ...@@ -66,7 +59,6 @@ node_types:
relationship: tosca.relationships.HostedOn relationship: tosca.relationships.HostedOn
interfaces: interfaces:
Standard: Standard:
configure: create: https://raw.githubusercontent.com/indigo-dc/tosca-types/master/artifacts/mysql/mysql_install.yml
implementation: playbooks/kubernetes_install.yaml
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
<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$/../Dockerfiles/planner/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/../Dockerfiles/planner/Dockerfile" 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.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../TOSCA/application_example.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$/src/planner/basic_planner.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/planner/basic_planner.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/planner/basic_planner.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/planner/basic_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/rpc_server.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/rpc_server.py" afterDir="false" />
</list> </list>
...@@ -18,18 +16,14 @@ ...@@ -18,18 +16,14 @@
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="true"> <file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/rpc_server.py"> <entry file="file://$PROJECT_DIR$/src/rpc_server.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor" />
<state relative-caret-position="152">
<caret line="113" selection-start-line="113" selection-end-line="118" selection-end-column="92" />
</state>
</provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/planner/basic_planner.py"> <entry file="file://$PROJECT_DIR$/src/planner/basic_planner.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="81"> <state relative-caret-position="171">
<caret line="19" selection-start-line="19" selection-end-line="19" /> <caret line="29" selection-start-line="29" selection-end-line="29" />
<folding> <folding>
<element signature="e#0#11#0" expanded="true" /> <element signature="e#0#11#0" expanded="true" />
</folding> </folding>
...@@ -87,6 +81,13 @@ ...@@ -87,6 +81,13 @@
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component> </component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/src/rpc_server.py" />
</list>
</option>
</component>
<component name="ProjectConfigurationFiles"> <component name="ProjectConfigurationFiles">
<option name="files"> <option name="files">
<list> <list>
...@@ -94,7 +95,7 @@ ...@@ -94,7 +95,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectFrameBounds"> <component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="33" /> <option name="x" value="33" />
<option name="y" value="13" /> <option name="y" value="13" />
<option name="width" value="922" /> <option name="width" value="922" />
...@@ -132,6 +133,7 @@ ...@@ -132,6 +133,7 @@
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="full.screen.before.presentation.mode" value="false" /> <property name="full.screen.before.presentation.mode" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" /> <property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="preferences.lookFeel" /> <property name="settings.editor.selected.configurable" value="preferences.lookFeel" />
...@@ -212,7 +214,7 @@ ...@@ -212,7 +214,7 @@
<servers /> <servers />
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="33" y="13" width="922" height="526" extended-state="0" /> <frame x="33" y="12" width="926" height="527" extended-state="6" />
<layout> <layout>
<window_info content_ui="combo" id="Project" order="0" weight="0.14317425" /> <window_info content_ui="combo" id="Project" order="0" weight="0.14317425" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" /> <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
...@@ -265,16 +267,12 @@ ...@@ -265,16 +267,12 @@
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/rpc_server.py"> <entry file="file://$PROJECT_DIR$/src/rpc_server.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor" />
<state relative-caret-position="152">
<caret line="113" selection-start-line="113" selection-end-line="118" selection-end-column="92" />
</state>
</provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/planner/basic_planner.py"> <entry file="file://$PROJECT_DIR$/src/planner/basic_planner.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="81"> <state relative-caret-position="171">
<caret line="19" selection-start-line="19" selection-end-line="19" /> <caret line="29" selection-start-line="29" selection-end-line="29" />
<folding> <folding>
<element signature="e#0#11#0" expanded="true" /> <element signature="e#0#11#0" expanded="true" />
</folding> </folding>
......
...@@ -12,12 +12,14 @@ import urllib.parse ...@@ -12,12 +12,14 @@ import urllib.parse
import sys import sys
import pdb import pdb
import names import names
import yaml
from pdb import set_trace as bp
class BasicPlanner: class BasicPlanner:
def __init__(self, path): def __init__(self, path):
self.template = ToscaTemplate(path) self.template = ToscaTemplate(path)
self.tosca_node_types = self.template.nodetemplates[0].type_definition.TOSCA_DEF self.tosca_node_types = self.template.nodetemplates[0].type_definition.TOSCA_DEF
...@@ -25,17 +27,18 @@ class BasicPlanner: ...@@ -25,17 +27,18 @@ class BasicPlanner:
self.all_nodes = {} self.all_nodes = {}
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())
capable_node_types = [] capable_node_types = []
node_templates = [] node_templates = []
for node in self.template.nodetemplates: for node in self.template.nodetemplates:
missing_requirements = self.get_missing_requirements(node) missing_requirements = self.get_missing_requirements(node)
for req in missing_requirements: for req in missing_requirements:
for key in req: for key in req:
capable_nodes = self.get_node_types_by_capability(req[key]['capability']) capable_nodes = self.get_node_types_by_capability(req[key]['capability'])
# remove nodes required once. e.g. kubernetes is hosting all dockers
for node_type in capable_nodes: for node_type in capable_nodes:
capable_node = capable_nodes[node_type] capable_node = capable_nodes[node_type]
for cap in capable_node['capabilities']: for cap in capable_node['capabilities']:
capability_type = capable_node['capabilities'][cap]['type'] capability_type = capable_node['capabilities'][cap]['type']
if capability_type == req[key]['capability'] and self.has_capability_max_one_occurrence(capable_node['capabilities'][cap]) and not self.contains_node_type(capable_node_types,node_type): if capability_type == req[key]['capability'] and self.has_capability_max_one_occurrence(capable_node['capabilities'][cap]) and not self.contains_node_type(capable_node_types,node_type):
...@@ -46,34 +49,41 @@ class BasicPlanner: ...@@ -46,34 +49,41 @@ class BasicPlanner:
break break
node.requirements.append(req) node.requirements.append(req)
node_templates.append(node) node_templates.append(node)
for node_type in capable_nodes:
capable_node = capable_nodes[node_type] for node_type in capable_node_types:
nodetemplate = {} nodetemplate_dict = {}
nodetemplate[names.get_first_name().lower()] = node_type type_name = next(iter(node_type))
print(nodetemplate) node_type_array = type_name.split(".")
name = names.get_first_name().lower() + "_" + node_type_array[len(node_type_array)-1].lower()
self.template.nodetemplates = node_templates nodetemplate_dict[name] = node_type[next(iter(node_type))].copy()
tpl_snippet = ''' nodetemplate_dict[name]['type'] = type_name
server: if 'capabilities' in nodetemplate_dict[name]:
type: tosca.my.nodes.Compute nodetemplate_dict[name].pop('capabilities')
properties: if 'requirements' in nodetemplate_dict[name]:
cpu_frequency: 0.05 GHz nodetemplate_dict[name].pop('requirements')
disk_size: 500 MB if 'capabilities' in nodetemplate_dict[name]:
mem_size: 1 MB nodetemplate_dict[name].pop('capabilities')
''' if 'derived_from' in nodetemplate_dict[name]:
nodetemplates = yamlparser.simple_parse(tpl_snippet) nodetemplate_dict[name].pop('derived_from')
# print(type(nodetemplates))
# nodetemplate = NodeTemplate('server', nodetemplates)
print('------------------')
# print(node.get_capabilities().keys)
if 'type' in node_type[next(iter(node_type))]:
node_type[next(iter(node_type))].pop('type')
nodetemplate = NodeTemplate(name, nodetemplate_dict,node_type)
node_templates.append(nodetemplate)
self.template.nodetemplates = node_templates
print('------------------')
# print(node.get_capabilities().keys)
def get_missing_requirements(self, node): def get_missing_requirements(self, node):
def_type = self.template._get_all_custom_defs()[node.type] def_type = self.all_nodes[node.type]
def_requirements = def_type['requirements'] def_requirements = def_type['requirements']
missing_requirements = [] missing_requirements = []
if not node.requirements: if not node.requirements:
missing_requirements = def_requirements missing_requirements = def_requirements
...@@ -84,12 +94,12 @@ class BasicPlanner: ...@@ -84,12 +94,12 @@ class BasicPlanner:
if key not in(node_req): if key not in(node_req):
missing_requirements.append(def_requirement) missing_requirements.append(def_requirement)
break break
if node.parent_type: if node.parent_type:
missing_requirements = missing_requirements + node.parent_type.requirements missing_requirements = missing_requirements + node.parent_type.requirements
return missing_requirements return missing_requirements
def get_node_types_by_capability(self,cap): def get_node_types_by_capability(self,cap):
candidate_nodes = {} candidate_nodes = {}
for tosca_node_type in self.all_nodes: for tosca_node_type in self.all_nodes:
...@@ -97,7 +107,7 @@ class BasicPlanner: ...@@ -97,7 +107,7 @@ class BasicPlanner:
for caps in self.all_nodes[tosca_node_type]['capabilities']: for caps in self.all_nodes[tosca_node_type]['capabilities']:
if 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] candidate_nodes[tosca_node_type] = self.all_nodes[tosca_node_type]
candidate_child_nodes = {} candidate_child_nodes = {}
for tosca_node_type in self.all_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 tosca_node_type.startswith('tosca.nodes') and 'derived_from' in self.all_nodes[tosca_node_type]:
...@@ -106,41 +116,41 @@ class BasicPlanner: ...@@ -106,41 +116,41 @@ class BasicPlanner:
if candidate_child_node['derived_from'] == candidate_node_name: if candidate_child_node['derived_from'] == candidate_node_name:
candidate_child_nodes[tosca_node_type] = self.all_nodes[tosca_node_type] candidate_child_nodes[tosca_node_type] = self.all_nodes[tosca_node_type]
candidate_child_nodes[tosca_node_type] = self.copy_capabilities_with_one_occurrences(candidate_nodes[candidate_node_name]['capabilities'],candidate_child_node) candidate_child_nodes[tosca_node_type] = self.copy_capabilities_with_one_occurrences(candidate_nodes[candidate_node_name]['capabilities'],candidate_child_node)
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"
for candidate_node_name in candidate_nodes: for candidate_node_name in candidate_nodes:
if 'interfaces' in candidate_nodes[candidate_node_name].keys(): if 'interfaces' in candidate_nodes[candidate_node_name].keys():
capable_nodes[candidate_node_name] = candidate_nodes[candidate_node_name] capable_nodes[candidate_node_name] = candidate_nodes[candidate_node_name]
return capable_nodes return capable_nodes
def copy_capabilities_with_one_occurrences(self,parent_capabilities,candidate_child_node): def copy_capabilities_with_one_occurrences(self,parent_capabilities,candidate_child_node):
inherited_capabilities = [] inherited_capabilities = []
if not 'capabilities' in candidate_child_node.keys(): if not 'capabilities' in candidate_child_node.keys():
candidate_child_node['capabilities'] = {} candidate_child_node['capabilities'] = {}
for capability in parent_capabilities: for capability in parent_capabilities:
inherited_capability = parent_capabilities[capability] inherited_capability = parent_capabilities[capability]
if self.has_capability_max_one_occurrence(inherited_capability): if self.has_capability_max_one_occurrence(inherited_capability):
inherited_capabilities.append(parent_capabilities) inherited_capabilities.append(parent_capabilities)
for key in parent_capabilities: for key in parent_capabilities:
candidate_child_node['capabilities'][key] = parent_capabilities[key] candidate_child_node['capabilities'][key] = parent_capabilities[key]
return candidate_child_node return candidate_child_node
def has_capability_max_one_occurrence(self,capability): def has_capability_max_one_occurrence(self,capability):
if 'occurrences' in capability and capability['occurrences'][1] == 1: if 'occurrences' in capability and capability['occurrences'][1] == 1:
return True return True
else: else:
return False return False
def contains_node_type(self,capable_node_types_list,node_type): def contains_node_type(self,capable_node_types_list,node_type):
for capable_node_type in capable_node_types_list: for capable_node_type in capable_node_types_list:
type_name = next(iter(capable_node_type)) type_name = next(iter(capable_node_type))
if type_name == node_type: if type_name == node_type:
return True return True
return False return False
\ No newline at end of file
...@@ -23,7 +23,7 @@ if not getattr(logger, 'handler_set', None): ...@@ -23,7 +23,7 @@ if not getattr(logger, 'handler_set', None):
h.setFormatter(formatter) h.setFormatter(formatter)
logger.addHandler(h) logger.addHandler(h)
logger.handler_set = True logger.handler_set = True
def init_chanel(args): def init_chanel(args):
...@@ -51,7 +51,7 @@ def on_request(ch, method, props, body): ...@@ -51,7 +51,7 @@ def on_request(ch, method, props, body):
ch.basic_publish(exchange='', ch.basic_publish(exchange='',
routing_key=props.reply_to, routing_key=props.reply_to,
properties=pika.BasicProperties(correlation_id=\ properties=pika.BasicProperties(correlation_id=
props.correlation_id), props.correlation_id),
body=str(response)) body=str(response))
ch.basic_ack(delivery_tag=method.delivery_tag) ch.basic_ack(delivery_tag=method.delivery_tag)
......
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