first commit

Change-Id: I8a65ee5527dd16d81e87c8ac5d4bdb471e5e759d
Signed-off-by: lombardof <flombardo@cnit.it>
diff --git a/projecthandler/__init__.py b/projecthandler/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/projecthandler/__init__.py
diff --git a/projecthandler/admin.py b/projecthandler/admin.py
new file mode 100644
index 0000000..d85d57a
--- /dev/null
+++ b/projecthandler/admin.py
@@ -0,0 +1,19 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from django.contrib import admin
+
+# Register your models here.
diff --git a/projecthandler/apps.py b/projecthandler/apps.py
new file mode 100644
index 0000000..b71d1e7
--- /dev/null
+++ b/projecthandler/apps.py
@@ -0,0 +1,21 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from django.apps import AppConfig
+
+
+class ProjecthandlerConfig(AppConfig):
+    name = 'projecthandler'
diff --git a/projecthandler/management/__init__.py b/projecthandler/management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/projecthandler/management/__init__.py
diff --git a/projecthandler/management/commands/__init__.py b/projecthandler/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/projecthandler/management/commands/__init__.py
diff --git a/projecthandler/management/commands/delete_project_type.py b/projecthandler/management/commands/delete_project_type.py
new file mode 100644
index 0000000..d750f9f
--- /dev/null
+++ b/projecthandler/management/commands/delete_project_type.py
@@ -0,0 +1,14 @@
+from django.core.management.base import BaseCommand, CommandError
+
+
+class Command(BaseCommand):
+    help = 'Delete a project type'
+
+    def handle(self, *args, **options):
+
+            try:
+                print 'delete project type'
+            except Exception:
+                raise CommandError('Error unable to delete a new project type')
+
+            self.stdout.write(self.style.SUCCESS('Project type successfully deleted'))
diff --git a/projecthandler/management/commands/new_project_type.py b/projecthandler/management/commands/new_project_type.py
new file mode 100644
index 0000000..7c9dce9
--- /dev/null
+++ b/projecthandler/management/commands/new_project_type.py
@@ -0,0 +1,14 @@
+from django.core.management.base import BaseCommand, CommandError
+
+
+class Command(BaseCommand):
+    help = 'Create a new project type'
+
+    def handle(self, *args, **options):
+
+            try:
+                print 'new project type'
+            except Exception:
+                raise CommandError('Error unable to create a new project type')
+
+            self.stdout.write(self.style.SUCCESS('New project type successfully created'))
diff --git a/projecthandler/models.py b/projecthandler/models.py
new file mode 100644
index 0000000..66fb7a5
--- /dev/null
+++ b/projecthandler/models.py
@@ -0,0 +1,333 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils import timezone
+import jsonfield
+from StringIO import StringIO
+import zipfile
+import json
+import yaml
+from lib.util import Util
+from model_utils.managers import InheritanceManager
+import logging
+import os, shutil
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger('models.py')
+
+project_types = {}
+
+
+class Project(models.Model):
+    """ Base class for project types
+
+    data_project stores a validated JSON representation of the project
+    get_dataproject() method returns the python dict representation of the project
+
+
+    """
+    owner = models.ForeignKey('sf_user.CustomUser', db_column='owner')
+    name = models.CharField(max_length=20, default='')
+    created_date = models.DateTimeField(default=timezone.now)
+    updated_date = models.DateTimeField(default=timezone.now, blank=True, null=True)
+    info = models.TextField(default='No info')
+    data_project = jsonfield.JSONField(default={})
+    """Stores a validated JSON representation of the project"""
+
+    validated = models.BooleanField(default=False)
+
+    #InheritanceManager
+    objects = InheritanceManager()
+   
+
+    @classmethod
+    def get_project_types(cls):
+        global project_types
+        return project_types        
+
+    @classmethod
+    def add_project_type(cls, type, my_class):
+        global project_types
+        project_types [type]= my_class
+
+
+    @classmethod
+    def create_project(cls, name, user, validated, info, data_project):
+        project = cls.objects.create(name=name, owner=user, validated=False, info=info,
+                                                       data_project=data_project)
+        return project
+
+    @classmethod
+    def get_graph_model(cls, file_path):
+        """Returns the model of the graph of the project type as a yaml object
+
+        Returns an empty dict if there is no file with the model
+        """
+        # file_path = GRAPH_MODEL_FULL_NAME
+        graph_model = {}
+        try:
+            graph_model = Util.loadyamlfile(file_path)
+        except Exception as e:
+            log.exception(e)
+            pass
+        return graph_model       
+
+    def get_type(self):
+        return "Base"
+
+    #@classmethod
+    def get_dataproject(self):
+        """ Return the python dict representation of the project data
+
+        """
+        #current_data = json.loads(self.data_project)
+        current_data = Util.json_loads_byteified(self.data_project)
+
+        return current_data
+
+    #@classmethod
+    def get_overview_data(self):
+        result = {
+            'owner': self.owner,
+            'name': self.name,
+            'updated_date': self.updated_date,
+            'info': self.info,
+            'validated': self.validated
+        }
+
+        return result
+
+    def set_data_project(self, new_data, validated):
+        self.data_project = new_data
+        self.set_validated(validated)
+        self.update()
+
+    def update(self):
+        self.updated_date = timezone.now()
+        self.save()
+
+    def __str__(self):
+        return self.name
+
+    def edit_graph_positions(self, positions):
+        # print positions
+        try:
+            current_data = json.loads(self.data_project)
+            if 'positions' not in current_data:
+                current_data['positions'] = {}
+            if 'vertices' not in current_data['positions']:
+                current_data['positions']['vertices'] = {}
+            if 'vertices' in positions:
+                current_data['positions']['vertices'].update(positions['vertices'])
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def get_descriptors(self, type_descriptor):
+        """Returns all descriptors of a given type"""
+
+        try:
+            current_data = json.loads(self.data_project)
+            result = current_data[type_descriptor]
+        except Exception as e:
+            log.debug(e)
+            result = {}
+        return result
+
+    def get_descriptor(self, descriptor_id, type_descriptor):
+        """Returns a specific descriptor"""
+
+        try:
+            current_data = json.loads(self.data_project)
+            result = current_data[type_descriptor][descriptor_id]
+            print descriptor_id, type_descriptor, result
+        except Exception as e:
+            log.debug(e)
+            result = {}
+
+        return result
+
+    def delete_descriptor(self, type_descriptor, descriptor_id):
+        try:
+            log.debug('delete descriptor'+ descriptor_id + ' ' + type_descriptor)
+            current_data = json.loads(self.data_project)
+            del (current_data[type_descriptor][descriptor_id])
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def clone_descriptor(self, type_descriptor, descriptor_id, new_id):
+        try:
+            current_data = json.loads(self.data_project)
+            descriptor = current_data[type_descriptor][descriptor_id]
+            new_descriptor = self.get_clone_descriptor(descriptor, type_descriptor, new_id)
+            current_data[type_descriptor][new_id] = new_descriptor
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def edit_descriptor(self, type_descriptor, descriptor_id, new_data, data_type):
+        try:
+
+            ##FIXME questa parte va completamente rivista cosi' ha varie lacune
+            #log.info('editing ',+ descriptor_id + ' ' + type_descriptor + ' ' + data_type)
+            current_data = json.loads(self.data_project)
+            new_descriptor = new_data
+            if data_type == 'json':
+                new_descriptor = json.loads(new_data)
+            elif data_type == 'yaml':
+                yaml_object = yaml.load(new_data)
+                new_descriptor = json.loads(Util.yaml2json(yaml_object))
+            if type_descriptor != 'click' and type_descriptor != 'oshi' and type_descriptor !='cran':
+                reference_schema = self.get_json_schema_by_type(type_descriptor)
+                Util.validate_json_schema(reference_schema, new_descriptor)
+            current_data[type_descriptor][descriptor_id] = new_descriptor
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def get_zip_archive(self):
+        in_memory = StringIO()
+        try:
+            current_data = json.loads(self.data_project)
+            zip = zipfile.ZipFile(in_memory, "w", zipfile.ZIP_DEFLATED)
+            for desc_type in current_data:
+                for current_desc in current_data[desc_type]:
+                    zip.writestr(current_desc + '.json', json.dumps(current_data[desc_type][current_desc]))
+
+            zip.close()
+        except Exception as e:
+            log.debug(e)
+
+        in_memory.flush()
+        return in_memory
+
+    def get_positions(self):
+        """Returns the positions of nodes"""
+        try:
+            current_data = json.loads(self.data_project)
+            positions = {}
+            if 'positions' in current_data:
+                positions = current_data['positions']
+        except Exception as e:
+            log.debug(e)
+
+        return positions
+
+    def get_deployment_descriptor(self, **kwargs):
+        """Returns the deployment descriptor"""
+        raise NotImplementedError
+
+    def get_node_overview(self, **kwargs):
+        """Returns the node overview"""
+        raise NotImplementedError
+
+    def get_all_ns_descriptors(self, nsd_id):
+        raise NotImplementedError
+
+    def translate_push_ns_on_repository(self, translator, nsd_id, repository, **kwargs):
+        raise NotImplementedError
+
+
+class ProjectStateless(Project):
+
+    def get_descriptors(self, type_descriptor):
+        """Returns all descriptors of a given type"""
+        raise NotImplementedError
+
+    def delete_descriptor(self, type_descriptor, descriptor_id):
+        raise NotImplementedError
+
+    def get_all_ns_descriptors(self, nsd_id):
+        pass
+
+    def translate_push_ns_on_repository(self, translator, nsd_id, repository, **kwargs):
+        pass
+
+    def get_deployment_descriptor(self, **kwargs):
+        pass
+
+    def get_node_overview(self, **kwargs):
+        pass
+
+    def get_dataproject(self):
+        raise NotImplementedError
+
+    def get_overview_data(self):
+        raise NotImplementedError
+
+class Repository(models.Model):
+    """ Repository
+    """
+    name = models.CharField(max_length=20, default='')
+    base_url = models.TextField(default='')
+    last_update = models.DateTimeField(default=timezone.now)
+    DIR_NAME = "/tmp/git_repo/"
+
+    def fetch_repository(self):
+        """
+        :return: git.remote.FetchInfo object
+        """
+        if os.path.isdir(self.DIR_NAME):
+            shutil.rmtree(self.DIR_NAME)
+
+        os.mkdir(self.DIR_NAME)
+        repo = git.Repo.init(self.DIR_NAME)
+        origin = repo.create_remote('origin', self.base_url)
+        origin.fetch()
+        fetch_info = origin.pull('master')[0]
+        return fetch_info
+
+    def push_repository(self, msg=None):
+        """
+        :param msg: Commit message
+        :return: git.remote.PushInfo object
+        """
+        repo = git.Repo.init(self.DIR_NAME)
+        origin = repo.remote('origin')
+        repo.git.add('--all')
+        repo.git.commit('-m \'[RDCL3D commit] ' + msg + '\'')
+        push_info = origin.push('master')[0]
+        return push_info
+
+    def to_json(self):
+        """
+        :return: JSON data of object
+        """
+        return {
+            'name': self.name,
+            'base_url': self.base_url.rstrip('\/'),
+            'last_update': self.last_update
+        }
diff --git a/projecthandler/osm_model.py b/projecthandler/osm_model.py
new file mode 100644
index 0000000..4776010
--- /dev/null
+++ b/projecthandler/osm_model.py
@@ -0,0 +1,328 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from __future__ import unicode_literals
+
+import copy
+import json
+import os.path
+import yaml
+from lib.util import Util
+import logging
+from projecthandler.models import ProjectStateless
+
+from lib.osm.osm_parser import OsmParser
+from lib.osm.osm_rdcl_graph import OsmRdclGraph
+from lib.osm.osmclient.client import Client
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger('OsmModel.py')
+
+
+PATH_TO_SCHEMAS = 'lib/osm/schemas/'
+PATH_TO_DESCRIPTORS_TEMPLATES = 'lib/osm/descriptor_template'
+DESCRIPTOR_TEMPLATE_SUFFIX = '.json'
+GRAPH_MODEL_FULL_NAME = 'lib/TopologyModels/osm/osm.yaml'
+EXAMPLES_FOLDER = 'usecases/OSM/'
+
+
+class OsmProject(ProjectStateless):
+    """Osm Project class
+    The data model has the following descriptors:
+        # descrtiptor list in comment #
+
+    """
+
+    def get_descriptors(self, type_descriptor):
+        """Returns all descriptors of a given type"""
+        log.debug("Get %s descriptors", type_descriptor)
+        try:
+            client = Client()
+            if type_descriptor == 'nsd':
+                result = client.nsd_list()
+
+            elif type_descriptor == 'vnfd':
+                result = client.vnfd_list()
+
+        except Exception as e:
+            log.exception(e)
+            result = {}
+        return result
+
+    def get_descriptor(self, descriptor_id, type_descriptor):
+        """Returns a specific descriptor"""
+        try:
+            client = Client()
+            if type_descriptor == 'nsd':
+                result = client.nsd_get(descriptor_id)
+                print result
+            elif type_descriptor == 'vnfd':
+                result = client.vnfd_get(descriptor_id)
+
+                print result
+        except Exception as e:
+            log.exception(e)
+            result = {}
+
+        return result
+
+    @classmethod
+    def data_project_from_files(cls, request):
+
+        file_dict = {}
+        for my_key in request.FILES.keys():
+            file_dict[my_key] = request.FILES.getlist(my_key)
+
+        log.debug(file_dict)
+
+        data_project = OsmParser.importprojectfiles(file_dict)
+
+        return data_project
+
+    @classmethod
+    def data_project_from_example(cls, request):
+        osm_id = request.POST.get('example-osm-id', '')
+        data_project = OsmParser.importprojectdir(EXAMPLES_FOLDER + osm_id + '/JSON', 'yaml')
+        return data_project
+
+    @classmethod
+    def get_example_list(cls):
+        """Returns a list of directories, in each directory there is a project osm"""
+
+        path = EXAMPLES_FOLDER
+        dirs = [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]
+        return {'osm': dirs}
+
+    @classmethod
+    def get_new_descriptor(cls, descriptor_type, request_id):
+
+        json_template = cls.get_descriptor_template(descriptor_type)
+
+        return json_template
+
+    @classmethod
+    def get_descriptor_template(cls, type_descriptor):
+        """Returns a descriptor template for a given descriptor type"""
+
+        try:
+            schema = Util.loadjsonfile(os.path.join(PATH_TO_DESCRIPTORS_TEMPLATES, type_descriptor + DESCRIPTOR_TEMPLATE_SUFFIX))
+            return schema
+        except Exception as e:
+            log.exception(e)
+            return False
+
+    @classmethod
+    def get_clone_descriptor(cls, descriptor, type_descriptor, new_descriptor_id):
+        new_descriptor = copy.deepcopy(descriptor)
+
+        return new_descriptor
+
+    def get_type(self):
+        return "osm"
+
+    def __str__(self):
+        return self.name
+
+    def get_overview_data(self):
+        current_data = json.loads(self.data_project)
+        client = Client()
+        nsd = client.nsd_list()
+        vnfd = client.vnfd_list()
+        ns = client.ns_list()
+        result = {
+            'owner': self.owner.__str__(),
+            'name': self.name,
+            'updated_date': self.updated_date.strftime('%Y-%m-%d %H:%M'),
+            'info': self.info,
+            'type': 'osm',
+            'nsd': len(nsd) if nsd else 0,
+            'vnfd': len(vnfd) if vnfd else 0,
+            'ns': len(ns) if ns else 0,
+            'validated': self.validated
+        }
+
+        return result
+
+    def get_graph_data_json_topology(self, descriptor_id):
+        rdcl_graph = OsmRdclGraph()
+        project = self.get_dataproject()
+        topology = rdcl_graph.build_graph_from_project(project,
+                                                     model=self.get_graph_model(GRAPH_MODEL_FULL_NAME))
+        return json.dumps(topology)
+
+    def create_descriptor(self, descriptor_name, type_descriptor, new_data, data_type, file_uploaded):
+        """Creates a descriptor of a given type from a json or yaml representation
+
+        Returns the descriptor id or False
+        """
+        log.debug('Create descriptor')
+
+        try:
+            client = Client()
+            if type_descriptor == 'nsd':
+                result = client.nsd_onboard(file_uploaded)
+            elif type_descriptor == 'vnfd':
+                result = client.vnfd_onboard(file_uploaded)
+
+            else:
+                log.debug('Create descriptor: Unknown data type')
+                return False
+
+        except Exception as e:
+            log.exception(e)
+            result = False
+        return result
+
+    def delete_descriptor(self, type_descriptor, descriptor_id):
+        log.debug('Delete descriptor')
+        try:
+            client = Client()
+            if type_descriptor == 'nsd':
+                result = client.nsd_delete(descriptor_id)
+            elif type_descriptor == 'vnfd':
+                result = client.vnfd_delete(descriptor_id)
+
+            else:
+                log.debug('Create descriptor: Unknown data type')
+                return False
+
+        except Exception as e:
+            log.exception(e)
+            result = False
+        return result
+
+    def edit_descriptor(self, type_descriptor, descriptor_id, new_data, data_type):
+        log.debug("Edit descriptor")
+        try:
+            client = Client()
+            if type_descriptor == 'nsd':
+                if data_type == 'yaml':
+                    new_data = yaml.load(new_data)
+                elif data_type == 'json':
+                    new_data = json.loads(new_data)
+                result = client.nsd_update(descriptor_id, new_data)
+            elif type_descriptor == 'vnfd':
+                if data_type == 'yaml':
+                    new_data = yaml.load(new_data)
+                elif data_type == 'json':
+                    new_data = json.loads(new_data)
+                result = client.vnfd_update(descriptor_id, new_data)
+
+            else:
+                log.debug('Create descriptor: Unknown data type')
+                return False
+        except Exception as e:
+            log.exception(e)
+            result = False
+        return result
+
+    def get_package_files_list(self, type_descriptor, descriptor_id):
+        try:
+            client = Client()
+            if type_descriptor == 'nsd':
+                result = client.nsd_artifacts(descriptor_id)
+            elif type_descriptor == 'vnfd':
+                result = client.vnf_packages_artifacts(descriptor_id)
+            else:
+                return False
+            result = yaml.load(result)
+            print result
+        except Exception as e:
+            log.exception(e)
+            result = False
+        print result
+        return result
+
+    def set_validated(self, value):
+        self.validated = True if value is not None and value == True else False
+
+    def get_add_element(self, request):
+        result = False
+
+        return result
+
+    def get_remove_element(self, request):
+        result = False
+
+        return result
+
+    def get_add_link(self, request):
+
+        result = False
+
+        return result
+
+    def get_remove_link(self, request):
+        result = False
+
+        return result
+
+    def create_ns(self, descriptor_type, descriptor_id, data_ns):
+        try:
+            client = Client()
+            if descriptor_type == 'nsd':
+                result = client.ns_create( data_ns)
+            else:
+                return False
+
+        except Exception as e:
+            log.exception(e)
+            result = False
+        print result
+        return result
+
+    def download_pkg(self, project, descriptor_id, descriptor_type):
+        try:
+            client = Client()
+            if descriptor_type == 'nsd':
+                result = client.get_nsd_pkg(descriptor_id)
+            elif descriptor_type == 'vnfd':
+                result = client.get_vnfd_pkg(descriptor_id)
+            else:
+                return False
+
+        except Exception as e:
+            log.exception(e)
+            result = False
+        print result
+        return result
+
+    def get_available_nodes(self, args):
+        """Returns all available node """
+        log.debug('get_available_nodes')
+        try:
+            result = []
+            #current_data = json.loads(self.data_project)
+            model_graph = self.get_graph_model(GRAPH_MODEL_FULL_NAME)
+            for node in model_graph['layer'][args['layer']]['nodes']:
+
+                current_data = {
+                    "id": node,
+                    "category_name": model_graph['nodes'][node]['label'],
+                    "types": [
+                        {
+                            "name": "generic",
+                            "id": node
+                        }
+                    ]
+                }
+                result.append(current_data)
+
+            #result = current_data[type_descriptor][descriptor_id]
+        except Exception as e:
+            log.debug(e)
+            result = []
+        return result
diff --git a/projecthandler/template/project/descriptor/descriptor_view_base.html b/projecthandler/template/project/descriptor/descriptor_view_base.html
new file mode 100644
index 0000000..3635d66
--- /dev/null
+++ b/projecthandler/template/project/descriptor/descriptor_view_base.html
@@ -0,0 +1,131 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+  	{{ block.super }}
+
+
+    <!-- Codemirror core CSS -->
+    <link rel="stylesheet" href="/static/bower_components/codemirror/lib/codemirror.css" >
+    <link rel="stylesheet" href="/static/bower_components/codemirror/addon/fold/foldgutter.css"  />
+    <link rel="stylesheet" href="/static/bower_components/codemirror/theme/neat.css" >
+    <link rel="stylesheet" href="/static/bower_components/codemirror/addon/dialog/dialog.css" >
+    <link rel="stylesheet" href="/static/bower_components/codemirror/addon/display/fullscreen.css" >
+
+{% endblock %}
+
+
+
+
+{% block content_body %}
+  	{{ block.super }}
+<div class="row">
+    <div class="col-md-12">
+    <div class="nav-tabs-custom">
+    <ul class="nav nav-tabs">
+        {% block tab_pane_button_list %}
+
+        {% endblock %}
+
+        {% block nav_buttons_list %}
+
+        {% endblock %}
+
+    </ul>
+    <div class="tab-content">
+        {% block tab_pane_list %}
+
+        {% endblock %}
+    </div>
+    <!-- /.tab-content -->
+
+
+
+
+</div>
+
+    </div>
+</div>
+{% endblock %}
+
+{% block resource_block %}
+  	{{ block.super }}
+
+
+    <script src="/static/bower_components/codemirror/lib/codemirror.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/fold/foldcode.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/fold/foldgutter.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/fold/brace-fold.js" ></script>
+    <script src="/static/bower_components/codemirror/mode/javascript/javascript.js" ></script>
+    <script src="/static/bower_components/codemirror/mode/yaml/yaml.js" ></script>
+    <script src="/static/bower_components/codemirror/mode/markdown/markdown.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/search/searchcursor.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/search/search.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/dialog/dialog.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/display/autorefresh.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/edit/matchbrackets.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/edit/closebrackets.js" ></script>
+    <script src="/static/bower_components/codemirror/addon/display/fullscreen.js" ></script>
+    <script src="/static/bower_components/codemirror/keymap/sublime.js" ></script>
+
+
+    <script>
+
+        var json_editor_settings = {
+            mode: "javascript",
+            showCursorWhenSelecting: true,
+            autofocus: true,
+            lineNumbers: true,
+            lineWrapping: true,
+            foldGutter: true,
+            gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
+            autoCloseBrackets: true,
+            matchBrackets: true,
+            extraKeys: {
+                "F11": function (cm) {
+                    cm.setOption("fullScreen", !cm.getOption("fullScreen"));
+                },
+                "Esc": function (cm) {
+                    if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
+                },
+                "Ctrl-Q": function (cm) {
+                    cm.foldCode(cm.getCursor());
+                }
+            },
+            theme: "neat",
+            keyMap: "sublime"
+        };
+
+        var yaml_editor_settings = {
+            mode: "yaml",
+            showCursorWhenSelecting: true,
+            autofocus: true,
+            autoRefresh: true,
+            lineNumbers: true,
+            lineWrapping: true,
+            foldGutter: true,
+            gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
+            autoCloseBrackets: true,
+            matchBrackets: true,
+            extraKeys: {
+                "F11": function (cm) {
+                    cm.setOption("fullScreen", !cm.getOption("fullScreen"));
+                },
+                "Esc": function (cm) {
+                    if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
+                },
+                "Ctrl-Q": function (cm) {
+                    cm.foldCode(cm.getCursor());
+                }
+            },
+            theme: "neat",
+            keyMap: "sublime"
+        };
+
+
+        function goToGraph() {
+            window.location.href = '/projects/{{project_id}}/graph?type={{descriptor_type}}&id={{descriptor_id}}'
+        }
+    </script>
+{% endblock %}
diff --git a/projecthandler/template/project/descriptor/modal/choose_node_id.html b/projecthandler/template/project/descriptor/modal/choose_node_id.html
new file mode 100644
index 0000000..3bfea9e
--- /dev/null
+++ b/projecthandler/template/project/descriptor/modal/choose_node_id.html
@@ -0,0 +1,27 @@
+<div class="modal" id="modal_choose_node_id" xmlns="http://www.w3.org/1999/html">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span></button>
+                <h4 class="modal-title" id="modal_chooser_title_add_node">Add node</h4>
+            </div>
+            <div class="modal-body">
+                <div id="div_chose_id">
+                    <label>Choose an id </label>
+                    <input name="input_choose_node_id" id="input_choose_node_id" type="text" size="40" maxlength="20"/>
+                </div>
+                {% block content_body %}
+
+                {% endblock %}
+            </div>
+
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Cancel</button>
+                <button type="button" class="btn btn-primary" id="save_choose_node_id">Add</button>
+            </div>
+        </div>
+        <!-- /.modal-content -->
+    </div>
+    <!-- /.modal-dialog -->
+</div>
\ No newline at end of file
diff --git a/projecthandler/template/project/modal/modal_keyboard_info_base.html b/projecthandler/template/project/modal/modal_keyboard_info_base.html
new file mode 100644
index 0000000..1986d5d
--- /dev/null
+++ b/projecthandler/template/project/modal/modal_keyboard_info_base.html
@@ -0,0 +1,37 @@
+<div id="modalTopologyInfoButton" class="modal fade" tabindex="-1" role="dialog">
+	<div class="modal-dialog ">
+		<div class="modal-content">
+			<div class="modal-header">
+
+				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
+					<span aria-hidden="true">&times;</span>
+				</button>
+				<h4 class="modal-title">Keyboard shortcuts</h4>
+			</div>
+			<div class="modal-body">
+                <ul>
+
+                    <li>
+                        <p>Create edge: Select the first vertex by clicking on it. <span class="help-key">Shift</span> + <span class="help-key">left-click</span> on another vertex (different than the selected one).</p>
+                    </li>
+                    <li>
+                        <p> <span class="help-key">Delete</span> Delete selected nodes or link.</p>
+                    </li>
+
+                    <li>
+                        <p>Switch to automatic node positioning: Play/Pause</p>
+                    </li>
+					{% block left_sidebar %}
+
+					{% endblock %}
+                </ul>
+			</div>
+			<div class="modal-footer">
+
+			</div>
+		</div>
+		<!-- /.modal-content -->
+	</div>
+	<!-- /.modal-dialog -->
+</div>
+<!-- /.modal -->
\ No newline at end of file
diff --git a/projecthandler/template/project/new_project.html b/projecthandler/template/project/new_project.html
new file mode 100644
index 0000000..44fb435
--- /dev/null
+++ b/projecthandler/template/project/new_project.html
@@ -0,0 +1,129 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+{{ block.super }}
+    <link rel="stylesheet" href="{% static "bower_components/admin-lte/plugins/select2/select2.css" %}">
+
+    <style type="text/css">
+
+  input:required:invalid, input:focus:invalid {
+
+    background-position: right top;
+    background-repeat: no-repeat;
+  }
+  input:required:valid {
+
+    background-position: right top;
+    background-repeat: no-repeat;
+  }
+
+</style>
+{% endblock %}
+
+{% block left_sidebar %}
+    {% include 'left_sidebar_base.html' %}
+{% endblock %}
+
+{% block breadcrumb_body %}
+{{ block.super }}
+<li><a href='{% url "projects:new_project" %}'>New Project</a></li>
+{% endblock %}
+
+{% block content_body %}
+{{ block.super }}
+<div class="row">
+    <div class="col-md-12">
+        <!-- general form elements -->
+        <div class="box box-primary">
+            <div class="box-header with-border">
+                <h3 class="box-title">New Project</h3>
+            </div>
+            <!-- /.box-header -->
+            <!-- form start -->
+            <form role="form" method="post" enctype="multipart/form-data">
+                {% csrf_token %}
+                <div class="box-body">
+                    <div class="row">
+                        <div class="form-group col-xs-3">
+                            <p for="typeButtonsSelect">Project Type</p>
+                            <input type="hidden" class="form-control input-sm" name="type" id="projectType"
+                                    required>
+                            <select id="select_type" class="js-example-basic-single form-control" style="width: 75%">
+
+                            </select>
+
+                        </div>
+                        <div class="form-group col-xs-4">
+                            <p for="projectName">Project Name</p>
+                            <input type="text" class="form-control input-sm" name="name" id="projectName"
+                                   placeholder="Enter Project name" required>
+                        </div>
+                        <div class="form-group col-xs-4">
+                            <p for="projectInfo">Info</p>
+                            <input type="text" class="form-control input-sm" name="info" id="projectInfo"
+                                   placeholder="Short Description">
+                        </div>
+
+
+                    </div>
+                    <div class="row">
+                        <div id="startGroup" class="form-group col-xs-5" style="display: none;">
+
+
+                            <div id="startButtonsSelect" class="btn-group" data-toggle="buttons">
+                                <label id="s-scratch" class="btn btn-primary active">
+                                    <input id="scratch" type="radio" name="startfrom" autocomplete="off" value="scratch">
+                                     Empty project
+                                </label>
+                                <label id="s-example" class="btn btn-primary">
+                                    <input type="radio" name="startfrom" autocomplete="off" value="example">
+                                     Example project
+                                </label>
+                                <label id="s-files" class="btn btn-primary">
+                                    <input type="radio" name="startfrom" autocomplete="off" value="files">
+                                     Load files
+                                </label>
+
+
+                            </div>
+                        </div>
+                    </div>
+                    <div id="typeStartContainer" class="row">
+                         <div class="form-group col-xs-8">
+                        {% autoescape off %}{{ type_container_template }}{% endautoescape %}
+                        </div>
+                    </div>
+
+                    <!-- /.box-body -->
+                </div>
+                <div class="box-footer">
+                    <button id="createButton" type="submit" class="btn btn-primary" disabled>Create</button>
+                </div>
+            </form>
+        </div>
+        <!-- /.box -->
+
+    </div>
+</div>
+{% endblock %}
+
+{% block resource_block %}
+{{ block.super }}
+    <!-- Select2 -->
+    <script src="{% static "bower_components/admin-lte/plugins/select2/select2.full.min.js" %}"></script>
+
+    <script src="{% static "src/projecthandler/new_project.js" %}"></script>
+<script>
+{% if data_type_selector %}
+var data_type_selector ={{ data_type_selector |safe }};
+{% endif %}
+
+{% if type_example_files %}
+var type_example_files = {{type_example_files | safe}};
+{% endif %}
+
+</script>
+{% endblock %}
+
diff --git a/projecthandler/template/project/osm/descriptor/descriptor_new.html b/projecthandler/template/project/osm/descriptor/descriptor_new.html
new file mode 100644
index 0000000..d257d7f
--- /dev/null
+++ b/projecthandler/template/project/osm/descriptor/descriptor_new.html
@@ -0,0 +1,155 @@
+{% extends "descriptor/descriptor_view_base.html" %}
+
+{% load staticfiles %}
+{% block head_base %}
+    {% with skin_css="AdminLTE/dist/css/skins/skin-purple.min.css"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+
+{% block body %}
+    {% with skin="purple"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+{% block logo_sidebar %}
+    {% with logo_mini="assets/img/osm_small_logo.png" logo="assets/img/OSM-logo.png"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+
+{% block title_header_big %}
+{{ block.super }}
+Onboard new {{ descriptor_type }} package
+{% endblock %}
+
+{% block left_sidebar %}
+{% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+{% block breadcrumb_body %}
+{{ block.super }}
+<li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview_data.name}}</a></li>
+<li><a href="{% url 'projects:open_project' project_id=project_id %}descriptors/{{descriptor_type}}">{{ descriptor_type }}  Descriptors</a></li>
+<li>Create Descriptor</li>
+{% endblock %}
+
+{% block tab_pane_button_list %}
+{{ block.super }}
+<li id="file_li" class="active"><a href="#upload" data-toggle="tab"><i class="fa fa-upload"></i> Onboard Package</a></li>
+{% endblock %}
+
+{% block nav_buttons_list %}
+{{ block.super }}
+<li class="pull-right">
+    <button id="cancel" type="button" class="btn btn-block btn-primary btn-sm" onclick="cancel(this.id)"><i
+            class="fa fa-times"></i> Cancel
+    </button>
+</li>
+{% endblock %}
+
+{% block tab_pane_list %}
+{{ block.super }}
+
+<div class="tab-pane active" id="upload">
+
+    <h4>Drag and drop file below</h4>
+    <div class="upload-drop-zone" id="drop-zone">
+            Just drag and drop files here
+    </div>
+</div>
+{% endblock %}
+
+
+{% block resource_block %}
+{{ block.super }}
+
+<script>
+
+    var dropZone = document.getElementById('drop-zone');
+    dropZone.ondrop = function(e) {
+        e.preventDefault();
+        this.className = 'upload-drop-zone';
+        create(e.dataTransfer.files, true);
+    }
+
+    dropZone.ondragover = function() {
+        this.className = 'upload-drop-zone drop';
+        return false;
+    }
+
+    dropZone.ondragleave = function() {
+        this.className = 'upload-drop-zone';
+        return false;
+    }
+
+
+
+
+        function create(fs, dropzone){
+            var id = $('.nav-tabs .active').attr('id');
+            if (dropzone) id = 'file_li'
+            var type, text ;
+            var data = new FormData();
+            switch(id) {
+
+                case 'file_li':
+                    type = 'file'
+
+                    var files = dropzone ? fs : document.getElementById('js-upload-files').files;
+                    if (!files || !files.length) {
+                      files = document.getElementById('drop-zone').files
+                      if(!files || !files.length){
+                        alert("Seletc a file")
+                        return
+                      }
+                    }
+                    console.log(files[0])
+                    var patt1 = /\.([0-9a-z]+)(?:[\?#]|$)/i;
+                    console.log(files[0].name.match(patt1));
+                    var extension = files[0].name.substr(files[0].name.lastIndexOf('.') + 1)
+                    console.log(extension)
+                    if(!(extension == 'gz' )){
+                        alert("The file must be .tar.gz");
+                        return
+                    }
+
+                     data.append('file', files[0]);
+                    break;
+            }
+            data.append('csrfmiddlewaretoken','{{csrf_token}}');
+            data.append('type', type);
+            data.append('text', text);
+            data.append('id', '{{descriptor_id}}');
+            console.log(text);
+            $.ajax({
+                    url: "new",
+                    type: 'POST',
+                    data: data,
+                    cache: false,
+                    contentType: false,
+                    processData: false,
+                    success: function(result) {
+                        console.log(result)
+
+                        window.location.href="/projects/{{project_id}}/descriptors/{{descriptor_type}}"
+
+                    },
+                    error: function(result) {
+                        showAlert(result);
+                    }
+                });
+        }
+
+    function cancel(id){
+        window.location.href="/projects/{{project_id}}/descriptors/{{descriptor_type}}"
+    }
+
+
+
+</script>
+{% endblock %}
+
+{% block footer %}
+    {% include "footer.html" %}
+{% endblock %}
diff --git a/projecthandler/template/project/osm/descriptor/descriptor_view.html b/projecthandler/template/project/osm/descriptor/descriptor_view.html
new file mode 100644
index 0000000..5a082de
--- /dev/null
+++ b/projecthandler/template/project/osm/descriptor/descriptor_view.html
@@ -0,0 +1,126 @@
+{% extends "descriptor/descriptor_view_base.html" %}
+
+{% load staticfiles %}
+
+
+{% block title_header_big %}
+{{ block.super }}
+Edit {{ descriptor_type|upper }} Descriptor
+{% endblock %}
+
+
+{% block left_sidebar %}
+{% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+{% block breadcrumb_body %}
+{{ block.super }}
+<li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview_data.name}}</a></li>
+<li><a href="{% url 'projects:open_project' project_id=project_id %}descriptors/{{descriptor_type}}">{{ descriptor_type }} Descriptors</a></li>
+<li><a>{{descriptor_id}}</a></li>
+{% endblock %}
+
+{% block tab_pane_button_list %}
+{{ block.super }}
+<li class="active" id="yaml_li"><a href="#yaml" data-toggle="tab"><i class="fa fa-file-code-o"></i> YAML</a></li>
+<li id="json_li"><a href="#json" data-toggle="tab"><i class="fa fa-file-code-o"></i> JSON</a></li>
+{% endblock %}
+
+{% block nav_buttons_list %}
+    {{ block.super }}
+    <li class="pull-right"><button id="save" type="button" class="btn btn-block btn-primary btn-sm"  onclick="update(this.id)" ><i class="fa fa-save"></i> Update</button></li>
+    <li class="pull-right"><button id="save_show_graph" type="button" class="btn btn-block btn-primary btn-sm"  onclick="update(this.id)" disabled><i class="fa fa-save"></i> Update and Show Graph</button></li>
+    <li class="pull-right"><button type="button" class="btn btn-block btn-primary btn-sm"  onclick="goToGraph()" disabled><i class="fa fa-sitemap"></i> Show Graph</button></li>
+{% endblock %}
+
+{% block tab_pane_list %}
+{{ block.super }}
+
+<!-- /.tab-pane -->
+<div class="active tab-pane" id="yaml">
+    <textarea id="code_editor_yaml">
+    </textarea>
+</div>
+<!-- /.tab-pane-->
+
+<div class="tab-pane" id="json">
+    <textarea id="code_editor_json">
+    </textarea>
+</div>
+
+{% endblock %}
+
+{% block resource_block %}
+{{ block.super }}
+
+
+<script>
+    var editorJSON;
+    var editorYaml;
+
+    $(document).ready(function () {
+        //var cmjsoneditor = CodeMirror.fromTextArea(document.getElementById("code_editor"), json_editor_settings);
+        var myJsonTextArea = document.getElementById("code_editor_json");
+        editorJSON = CodeMirror(function (elt) {
+            myJsonTextArea.parentNode.replaceChild(elt, myJsonTextArea);
+        }, json_editor_settings);
+
+
+        editorJSON.setValue(JSON.stringify({{descriptor_strings.descriptor_string_json | safe}}, null, "\t"));
+        editorJSON.setOption("autoRefresh", true);
+        var myYamlTextArea = document.getElementById("code_editor_yaml");
+        editorYaml = CodeMirror(function (elt) {
+            myYamlTextArea.parentNode.replaceChild(elt, myYamlTextArea);
+        }, yaml_editor_settings);
+        var des_strings = {{descriptor_strings | safe}};
+        editorYaml.setValue(des_strings.descriptor_string_yaml);
+
+    });
+
+
+    function update(e) {
+        var dialog = bootbox.dialog({
+            message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
+            closeButton: false
+        });
+
+        var id = $('.nav-tabs .active').attr('id');
+        var type, text;
+        switch (id) {
+            case 'yaml_li':
+                type = 'yaml';
+                text = editorYaml.getValue();
+                break;
+            case 'json_li':
+                type = 'json';
+                text = editorJSON.getValue();
+                break;
+        }
+        $.ajax({
+            url: "/projects/{{project_id}}/descriptors/{{descriptor_type}}/{{descriptor_id}}/",
+            type: 'POST',
+            dataType: 'json',
+            data: {
+                'csrfmiddlewaretoken': '{{csrf_token}}',
+                'type': type,
+                'text': text
+            },
+            success: function (result) {
+                dialog.modal('hide');
+
+            },
+            error: function (result) {
+                console.log(result);
+                dialog.modal('hide');
+                bootbox.alert(result);
+            }
+        });
+    }
+
+</script>
+{% endblock %}
+
+
+{% block footer %}
+    {% include "footer.html"  %}
+{% endblock %}
diff --git a/projecthandler/template/project/osm/descriptor/descriptorlist.html b/projecthandler/template/project/osm/descriptor/descriptorlist.html
new file mode 100644
index 0000000..56ee44d
--- /dev/null
+++ b/projecthandler/template/project/osm/descriptor/descriptorlist.html
@@ -0,0 +1,57 @@
+{% load staticfiles %}
+{% load get %}
+<div class="col-md-12">
+
+    <div class="box">
+        <div class="box-header with-border">
+            <h3 class="box-title">
+            </h3>
+            <div class="box-tools">
+
+                <a href="{% url 'projects:new_descriptor' project_id=project_id descriptor_type=descriptor_type %}"
+                   class="btn btn-block btn-primary btn-sm"><i
+                        class="fa fa-upload"></i><span> Onboard {{descriptor_type|upper}}</span></a>
+            </div>
+        </div>
+        <div class="box-body">
+            <table id="descriptors_table" class="table table-bordered table-striped dataTable"
+                       role="grid">
+                <thead>
+                <tr role="row">
+                    <th>Id</th>
+                    <th>Name</th>
+                    <th>Description</th>
+                    <th style="width:10%">Vendor</th>
+                    <th style="width:5%">Version</th>
+                    <th style="width:35%">Actions</th>
+                </tr>
+                </thead>
+                <tbody>
+                {% for k in descriptors %}
+                <tr role="row">
+                    <td>{{ k|get:"_id" }}</td>
+                    <td>{{ k|get:"short-name" }} </td>
+                    <td>{{ k|get:"description" }} </td>
+                    <td>{{ k|get:"vendor" }} </td>
+                    <td>{{ k|get:"version" }} </td>
+                    <td>
+                        <div class="btn-group">
+                            {% if descriptor_type == "nsd" %}
+                            <button type="button" class="btn btn-default" data-container="body" data-toggle="tooltip" data-placement="top" title="Instantiate NS" onclick="javascript:openModalCreateNS('{{project_id}}', '{{descriptor_type}}', '{{ k|get:"_id" }}')"><i class="fa fa-paper-plane"></i></button>
+                            {% endif %}
+                            <button type="button" class="btn btn-default" data-container="body" data-toggle="tooltip" data-placement="top" title="Edit" onclick="javascript:openDescriptorView('{{project_id}}', '{{descriptor_type}}', '{{ k|get:"_id" }}')"><i class="fa fa-edit"></i></button>
+                            <button type="button" class="btn btn-default" data-container="body" data-toggle="tooltip" data-placement="top" title="Show content" onclick="javascript:openPackageContentList('{{project_id}}', '{{descriptor_type}}', '{{ k|get:"_id" }}')"><i class="fa fa-folder-open"></i></button>
+                            <button type="button" class="btn btn-default" data-container="body" data-toggle="tooltip" data-placement="top" title="Show Graph" onclick="location.href='/projects/{{project_id}}/graph?type={{descriptor_type}}&id={{ k|get:"_id" }}'" disabled><i class="fa fa-sitemap fa-fw"></i></button>
+                            <button type="button" class="btn btn-default" data-container="body" data-toggle="tooltip" data-placement="top" title="Download package" onclick="location.href='{% url 'projects:custom_action' project_id=project_id descriptor_type=descriptor_type descriptor_id=k|get:'_id' action_name='download_pkg' %}'"><i class="fa fa-download fa-fw"></i></button>
+                            <button type="button" class="btn btn-default" data-container="body" data-toggle="tooltip" data-placement="top" title="Delete" onclick="javascript:deletePackage('{{project_id}}', '{{descriptor_type}}', '{{ k|get:"_id" }}')"><i class="fa fa-trash-o"></i></button>
+                        </div>
+
+                    </td>
+                </tr>
+                {% endfor %}
+                </tbody>
+
+            </table>
+        </div>
+    </div>
+</div>
diff --git a/projecthandler/template/project/osm/descriptor/modal/choose_node_id.html b/projecthandler/template/project/osm/descriptor/modal/choose_node_id.html
new file mode 100644
index 0000000..91c4d20
--- /dev/null
+++ b/projecthandler/template/project/osm/descriptor/modal/choose_node_id.html
@@ -0,0 +1 @@
+{% extends "descriptor/modal/choose_node_id.html" %}
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/descriptor/modal/create_link_chooser.html b/projecthandler/template/project/osm/descriptor/modal/create_link_chooser.html
new file mode 100644
index 0000000..ed9a4a5
--- /dev/null
+++ b/projecthandler/template/project/osm/descriptor/modal/create_link_chooser.html
@@ -0,0 +1,21 @@
+<div class="modal" id="modal_create_link_chooser">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">×</span></button>
+        <h4 class="modal-title" id="modal_chooser_title">Default Modal</h4>
+      </div>
+      <div class="modal-body" >
+          <select class="form-control" id="selection_chooser">
+          </select>
+    </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary" id="save_chooser">Save changes</button>
+      </div>
+    </div>
+    <!-- /.modal-content -->
+  </div>
+  <!-- /.modal-dialog -->
+</div>
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/modal/files_list.html b/projecthandler/template/project/osm/modal/files_list.html
new file mode 100644
index 0000000..13105fe
--- /dev/null
+++ b/projecthandler/template/project/osm/modal/files_list.html
@@ -0,0 +1,33 @@
+<div class="modal" id="modal_files_list" xmlns="http://www.w3.org/1999/html">
+    <div   class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span></button>
+                <h4 id="files_list_tbody_title" class="modal-title"></h4>
+            </div>
+
+            <div class="modal-body" id="modal_files_list_body" >
+                <table id="files_list" class="table table-condensed">
+        <tbody id="files_list_tbody">
+            <tr>
+                <th style="width: 10px">#</th>
+                <th>File Name</th>
+                <th>Actions</th>
+            </tr>
+            <tr>
+                <td>-</td>
+                <td>name</td>
+                <td>-</td>
+            </tr>
+        </tbody>
+    </table>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
+            </div>
+        </div>
+        <!-- /.modal-content -->
+    </div>
+    <!-- /.modal-dialog -->
+</div>
diff --git a/projecthandler/template/project/osm/modal/modal_keyboard_info.html b/projecthandler/template/project/osm/modal/modal_keyboard_info.html
new file mode 100644
index 0000000..bf39e69
--- /dev/null
+++ b/projecthandler/template/project/osm/modal/modal_keyboard_info.html
@@ -0,0 +1 @@
+{% extends "modal/modal_keyboard_info_base.html" %}
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/osm_new_project.html b/projecthandler/template/project/osm/osm_new_project.html
new file mode 100644
index 0000000..cfdec29
--- /dev/null
+++ b/projecthandler/template/project/osm/osm_new_project.html
@@ -0,0 +1,25 @@
+<div id="div-file-upload-osm" class="start-selector"  style="display: none;">
+    <h4>Select Descriptors File from your computer</h4>
+
+    <div class="tab-pane col-md-6" >
+
+        <!-- Standar Form -->
+        <h3>Descriptor</h3>
+        <div class="form-inline">
+            <div class="form-group">
+                <input type="file"  name="ns_files" id="ns-js-upload-files" multiple>
+            </div>
+        </div>
+
+    </div>
+
+</div>
+
+<div id="div-example-osm" class="start-selector" style="display: none;">
+
+    <select id="example-osm" class="example-selector" data-type="osm" name="example-osm-id">
+
+    </select>
+
+
+</div>
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/osm_project_delete.html b/projecthandler/template/project/osm/osm_project_delete.html
new file mode 100644
index 0000000..50bf685
--- /dev/null
+++ b/projecthandler/template/project/osm/osm_project_delete.html
@@ -0,0 +1,36 @@
+{% extends "project_delete.html" %}
+
+{% block head_base %}
+    {% with skin_css="AdminLTE/dist/css/skins/skin-purple.min.css"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+
+{% block body %}
+    {% with skin="purple"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+{% block logo_sidebar %}
+    {% with logo_mini="assets/img/osm_small_logo.png" logo="assets/img/OSM-logo.png"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+
+{% block head_block %}
+  	{{ block.super }}
+
+{% endblock %}
+
+{% block left_sidebar %}
+    {% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+
+{% endblock %}
+
+{% block footer %}
+    {% include "footer.html" %}
+{% endblock %}
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/osm_project_descriptors.html b/projecthandler/template/project/osm/osm_project_descriptors.html
new file mode 100644
index 0000000..30ea76a
--- /dev/null
+++ b/projecthandler/template/project/osm/osm_project_descriptors.html
@@ -0,0 +1,121 @@
+{% extends "project_descriptors.html" %}
+{% load staticfiles %}
+
+
+{% block head_block %}
+  	{{ block.super }}
+<link rel="stylesheet" href="/static/bower_components/select2/dist/css/select2.min.css">
+{% endblock %}
+
+{% block title_header_big %}
+    {{ block.super }}
+  {% if descriptor_type  %}
+     {{ descriptor_type|upper }}
+  {% else%}
+    Undefined
+  {% endif %} Packages
+{% endblock %}
+
+{% block left_sidebar %}
+    {% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+    <li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview_data.name}}</a></li>
+    <li><a> {% if descriptor_type  %}
+     {{ descriptor_type }}
+  {% else%}
+    Undefined
+  {% endif %} Packages</a></li>
+
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+{% include 'osm/modal/files_list.html' %}
+{% include 'modal/instance_create.html' %}
+<div class="row">
+    {% include "osm/descriptor/descriptorlist.html" %}
+</div>
+{% endblock %}
+
+
+
+
+{% block resource_block %}
+  	{{ block.super }}
+    <script src="/static/bower_components/select2/dist/js/select2.js"></script>
+    <script>
+        function deletePackage(project_id, descriptor_type, package_id) {
+            bootbox.confirm("Are you sure want to delete?", function (result) {
+                if (result) {
+                    location.href = '/projects/' + project_id + '/descriptors/' + descriptor_type + '/' + package_id + '/delete'
+                }
+            })
+        }
+
+        function openModalCreateNS(project_id, descriptor_type, descriptor_id) {
+            select2_groups = $('#vimAccountId').select2({
+                placeholder: 'Select VIM',
+                ajax: {
+                    url: '{% url "vim:list" %}',
+                    dataType: 'json',
+                    processResults: function (data) {
+                        vims = [];
+                        if (data['datacenters']){
+                            for(d in data['datacenters']){
+                            var datacenter = data['datacenters'][d];
+                            vims.push({id: datacenter['_id'], text: datacenter['name']})
+                        }
+                        }
+
+                        return {
+                            results: vims
+                        };
+                    }
+                }
+            });
+            $('#nsdId').val(descriptor_id);
+            $('#modal_new_instance').modal('show');
+        }
+
+        function openPackageContentList(project_id, type, pkg_id) {
+            var dialog = bootbox.dialog({
+                message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
+                closeButton: true
+            });
+            $.ajax({
+                url: '/projects/' + project_id + '/descriptors/' + type + '/' + pkg_id + '/action/get_package_files_list',
+                type: 'GET',
+                dataType: "json",
+                contentType: "application/json;charset=utf-8",
+                success: function (result) {
+                    //$('#modal_show_vim_body').empty();
+                    console.log(result)
+                    dialog.modal('hide');
+                    build_file_list("Files in " + pkg_id, result.files);
+                },
+                error: function (result) {
+                    dialog.modal('hide');
+                    bootbox.alert("An error occurred while retrieving the package content.");
+                }
+            });
+        }
+
+
+        function build_file_list(title, list) {
+            $('#files_list_tbody').find('tr:gt(0)').remove();
+            $('#files_list_tbody_title').text(title)
+            for (var i in list) {
+                var template = '<tr><td>-</td><td>' + list[i] + '</td><td><button type="button" class="btn btn-default" onclick="" disabled><i class="fa fa-folder-open"></i></button></td></tr>'
+                $('#files_list_tbody').append(template)
+            }
+            $('#modal_files_list').modal('show');
+        }
+    </script>
+{% endblock %}
+
+{% block footer %}
+    {% include "footer.html"  %}
+{% endblock %}
diff --git a/projecthandler/template/project/osm/osm_project_details.html b/projecthandler/template/project/osm/osm_project_details.html
new file mode 100644
index 0000000..ab90385
--- /dev/null
+++ b/projecthandler/template/project/osm/osm_project_details.html
@@ -0,0 +1,79 @@
+{% extends "project_details.html" %}
+{% block head_base %}
+    {{ block.super }}
+{% endblock %}
+
+{% block body %}
+        {{ block.super }}
+{% endblock %}
+{% block logo_sidebar %}
+        {{ block.super }}
+{% endblock %}
+
+{% block left_sidebar %}
+    {% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+{% block content_body %}
+
+<div class="row">
+    <div class="col-md-6">
+        <div class="box box-widget">
+            <div class="box-footer no-padding">
+                <ul class="nav nav-stacked">
+                    <li><a><b>Project Name:</b> <span
+                        class="pull-right">{{project_overview.name}}</span></a>
+                    </li>
+                    <li><a><b>Info:</b> <span
+                            class="pull-right">{{project_overview.info}}</span></a></li>
+                    <li><a><b>Last updated:</b> <span
+                        class="pull-right">{{project_overview.updated_date}}</span></a>
+                    </li>
+                    <li><a><b>Owner:</b> <span
+                            class="pull-right">{{project_overview.owner}}</span></a></li>
+                </ul>
+
+            </div>
+
+        </div>
+    </div>
+    <div class="col-md-6">
+        <div class="row">
+            <div class="col-md-6 ">
+                <div class="small-box bg-aqua">
+                    <div class="inner"><h3>{{ project_overview.nsd }}</h3>
+                        <p>NS packages</p></div>
+                    <div class="icon"><i class="fa fa-archive"></i></div>
+                    <a href="/projects/{{ project_id }}/descriptors/nsd" class="small-box-footer">Open list <i
+                            class="fa fa-arrow-circle-right"></i></a></div>
+            </div>
+            <div class="col-md-6 ">
+                <div class="small-box bg-aqua">
+                    <div class="inner"><h3>{{ project_overview.vnfd }}</h3>
+                        <p>VNF packages</p></div>
+                    <div class="icon"><i class="fa fa-archive"></i></div>
+                    <a href="/projects/{{ project_id }}/descriptors/vnfd" class="small-box-footer">Open list <i
+                            class="fa fa-arrow-circle-right"></i></a></div>
+            </div>
+        </div>
+        <div class="row">
+            <div class="col-md-6 ">
+                <div class="small-box bg-maroon">
+                    <div class="inner"><h3>{{ project_overview.ns }}</h3>
+                        <p>NS Instances</p></div>
+                    <div class="icon"><i class="fa fa-list"></i></div>
+                    <a href='{% url "projects:instances:list" project_id=project_id type="ns"  %}' class="small-box-footer">Open list <i
+                            class="fa fa-arrow-circle-right"></i></a></div>
+            </div>
+
+        </div>
+
+    </div>
+</div>
+
+{% endblock %}
+
+
+{% block footer %}
+    {% include "footer.html" %}
+{% endblock %}
diff --git a/projecthandler/template/project/osm/osm_project_left_sidebar.html b/projecthandler/template/project/osm/osm_project_left_sidebar.html
new file mode 100644
index 0000000..029ae11
--- /dev/null
+++ b/projecthandler/template/project/osm/osm_project_left_sidebar.html
@@ -0,0 +1,56 @@
+<aside class="main-sidebar">
+    <!-- sidebar: style can be found in sidebar.less -->
+    <section class="sidebar">
+      <!-- sidebar menu: : style can be found in sidebar.less -->
+      <ul class="sidebar-menu" data-widget="tree">
+        <li class="header">MAIN NAVIGATION</li>
+        {% url "home" as  home_url %}
+          <li {% if request.get_full_path == home_url %} class="active" {% endif %} ><a href='{% url "home" %}'><i class="fa fa-home fa-fw"></i><span>Home</span></a></li>
+          <li class="header">PROJECT</li>
+          {% url "projects:open_project"  project_id=project_id as  project_url %}
+          <li {% if request.get_full_path == project_url %} class="active" {% endif %} >
+              <a href='{% url "projects:open_project"  project_id=project_id%}'>
+                  <i class="fa fa-file-text fa-fw"></i><span>Overview</span>
+              </a>
+          </li>
+          {% url "projects:list_descriptors"  project_id=project_id descriptor_type="vnfd" as  nsd_list_url %}
+          {% url "projects:list_descriptors"  project_id=project_id descriptor_type='vnfd' as  vnfd_list_url %}
+        <li {% if request.get_full_path == nsd_list_url %} class="active treeview" {% else %} class="treeview" {% endif %} >
+                <a href="#">
+                    <i class="fa fa-archive fa-fw"></i> <span>Packages {{nsd_list}}</span>
+                    <span class="pull-right-container">
+                        <i class="fa fa-angle-left pull-right"></i>
+                    </span>
+                </a>
+                <ul class="treeview-menu">
+                    <li {% if request.get_full_path == nsd_list_url %} class="active" {% endif %}>
+                        <a href="/projects/{{project_id}}/descriptors/nsd">
+                            <i class="fa fa-archive fa-fw"></i>NS Packages
+                        </a>
+                    </li>
+                    <li {% if request.get_full_path == vnfd_list_url %} class="active" {% endif %}>
+                        <a href="/projects/{{project_id}}/descriptors/vnfd">
+                            <i class="fa fa-archive fa-fw"></i>VNF Packages
+                        </a>
+                    </li>
+
+                </ul>
+            </li>
+            {% url "projects:instances:list" project_id=project_id type='ns' as  instance_ns_list_url %}
+            <li {% if request.get_full_path == instance_ns_list_url %} class="active" {% endif %} >
+                <a href='{% url "projects:instances:list" project_id=project_id  type="ns"%}'>
+                    <i class="fa fa-list fa-fw"></i><span>NS Instances</span>
+                </a>
+            </li>
+            <li class="header">CONFIG</li>
+            {% url "vim:list"  type='ns' as  vim_list_url %}
+             <li {% if request.get_full_path == vim_list_url %} class="active" {% endif %}>
+                 <a href='{% url "vim:list" %}'>
+                     <i class="fa fa-list fa-fw"></i><span>VIM Accounts</span>
+                 </a>
+             </li>
+
+      </ul>
+    </section>
+    <!-- /.sidebar -->
+  </aside>
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/project_graph.html b/projecthandler/template/project/osm/project_graph.html
new file mode 100644
index 0000000..15d2eeb
--- /dev/null
+++ b/projecthandler/template/project/osm/project_graph.html
@@ -0,0 +1,61 @@
+{% extends "project_graph_base.html" %}
+
+{% load staticfiles %}
+{% block head_base %}
+    {% with skin_css="AdminLTE/dist/css/skins/skin-purple.min.css"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+
+{% block body %}
+    {% with skin="purple"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+{% block logo_sidebar %}
+    {% with logo_mini="assets/img/osm_small_logo.png" logo="assets/img/OSM-logo.png"%}
+        {{ block.super }}
+    {% endwith %}
+{% endblock %}
+
+{% block title_header_big %}
+    {{ block.super }}
+{% endblock %}
+
+{% block left_sidebar %}
+    {% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+{% block topology_toolbar %}
+    {{ block.super }}
+        {% include 'osm/topology_toolbar.html' %}
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+ {% csrf_token %}
+
+
+{% include 'osm/descriptor/modal/create_link_chooser.html' %}
+{% include 'osm/descriptor/modal/choose_node_id.html' %}
+{% include 'osm/modal/modal_keyboard_info.html' %}
+{% endblock %}
+
+{% block resource_block %}
+  	{{ block.super }}
+
+    <script src="{% static "topology3D/js/model_graph_editor.js" %}"></script>
+    <!-- osm -->
+    <script src="{% static "src/projecthandler/osm/gui_properties.js" %}"></script>
+    <script src="{% static "src/projecthandler/osm/project_graph.js" %}"></script>
+    <script src="{% static "src/projecthandler/osm/controller.js" %}"></script>
+
+<script>
+    graph_editor.project_id = '{{project_id}}'
+
+</script>
+{% endblock %}
+
+{% block footer %}
+    {% include "footer.html"  %}
+{% endblock %}
\ No newline at end of file
diff --git a/projecthandler/template/project/osm/topology_toolbar.html b/projecthandler/template/project/osm/topology_toolbar.html
new file mode 100644
index 0000000..9a1f528
--- /dev/null
+++ b/projecthandler/template/project/osm/topology_toolbar.html
@@ -0,0 +1,6 @@
+{% extends 'topology_toolbar.html' %}
+
+{% block topology_toolbar_buttons %}
+    {{ block.super }}
+
+{% endblock %}
diff --git a/projecthandler/template/project/project_delete.html b/projecthandler/template/project/project_delete.html
new file mode 100644
index 0000000..e6afc5e
--- /dev/null
+++ b/projecthandler/template/project/project_delete.html
@@ -0,0 +1,73 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+  	{{ block.super }}
+
+{% endblock %}
+
+{% block left_sidebar %}
+
+{% endblock %}
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+    {% if project_id  %}
+    <li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview_data.name}}</a></li>
+    <li>Delete Project</li>
+    {% endif %}
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+    <div class="row">
+    {% if project_id  %}
+        <div class="col-sm-5">
+      <div class="box box-danger">
+        <div class="box-header with-border">
+              <i class="fa fa-warning"></i>
+
+              <h3 class="box-title">Warning</h3>
+        </div>
+          <div class="box-body">
+              <form role="form" method="post">
+                  {% csrf_token %}
+                  <div class="box-body">
+                        <p>The Project <strong>{{project_name}}</strong> will be deleted!</p>
+                      <!-- /.box-body -->
+                  </div>
+                   <div class="box-footer">
+                          <button type="submit" class="btn btn-danger pull-right"><i class="fa fa-trash"></i> Delete</button>
+                   </div>
+              </form>
+
+        </div><!-- /.box-body -->
+      </div><!-- /.box -->
+    </div>
+    {% endif %}
+</div>
+
+{% endblock %}
+
+{% block resource_block %}
+  	{{ block.super }}
+
+
+    <script>
+
+
+
+
+$(document).ready(function () {
+    {% if project_id == None %}
+      window.location.href='{% url "home"  %}';
+    {% endif %}
+
+});
+
+
+
+    </script>
+{% endblock %}
+
diff --git a/projecthandler/template/project/project_descriptors.html b/projecthandler/template/project/project_descriptors.html
new file mode 100644
index 0000000..6f7345e
--- /dev/null
+++ b/projecthandler/template/project/project_descriptors.html
@@ -0,0 +1,54 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+  	{{ block.super }}
+    <link rel="stylesheet" href="/static/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
+{% endblock %}
+{% block title_header_big %}
+
+{% endblock %}
+
+{% block left_sidebar %}
+
+{% endblock %}
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+    <li><a href="{% url 'projects:projects_list' %}">Projects</a></li>
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+{% if alert_message %}
+    {% if alert_message.success %}
+        <div class="alert alert-success alert-dismissible fade in">
+            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+            <h4><i class="icon fa fa-check"></i> Success</h4>
+            {{alert_message.message}}
+        </div>
+    {% endif %}
+    {% if not alert_message.success %}
+        <div class="alert alert-danger alert-dismissible fade in">
+            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+            <h4><i class="icon fa fa-ban"></i> Alert!</h4>
+            {{alert_message.message}}
+        </div>
+    {% endif %}
+{% endif %}
+
+{% endblock %}
+
+
+
+
+{% block resource_block %}
+  	{{ block.super }}
+
+    <script src="/static/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
+    <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
+    <script src="/static/src/projecthandler/descriptorslist.js"></script>
+
+{% endblock %}
+
diff --git a/projecthandler/template/project/project_details.html b/projecthandler/template/project/project_details.html
new file mode 100644
index 0000000..e944e0d
--- /dev/null
+++ b/projecthandler/template/project/project_details.html
@@ -0,0 +1,78 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+  	{{ block.super }}
+
+{% endblock %}
+
+{% block left_sidebar %}
+    {{ block.super }}
+
+{% endblock %}
+
+{% block title_header_big %}
+    {{ block.super }}
+    {{project_overview.name}}
+{% endblock %}
+
+{% block title_header_small %}
+    {{ block.super }}
+    Overview
+{% endblock %}
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+    <li><a href="{% url 'projects:projects_list' %}">Projects</a></li>
+    <li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview.name}}</a></li>
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+<div class="row">
+    <div class="col-md-6">
+        <div class="box box-widget">
+            <div class="box-footer no-padding">
+                <ul class="nav nav-stacked">
+                    <li><a><b>Project Name:</b> <span class="pull-right">{{project_overview.name}}</span></a>
+                    </li>
+                    <li><a><b>Info:</b> <span
+                            class="pull-right">{{project_overview.info}}</span></a></li>
+                    <li><a><b>Last updated:</b> <span class="pull-right">{{project_overview.updated_date}}</span></a>
+                    </li>
+                    <li><a><b>Owner:</b> <span
+                            class="pull-right">{{project_overview.owner}}</span></a></li>
+
+                    <li><a><b>Validated:</b>
+                        {% if project_overview.validated %}
+                        <span class="pull-right badge bg-green">{{project_overview.validated}}</span>
+                        {% else %}
+                        <span class="pull-right badge bg-red">{{project_overview.validated}}</span>
+                        {% endif %}
+                    </a>
+
+                    </li>
+
+                </ul>
+
+            </div>
+
+        </div>
+    </div>
+    <div class="col-md-6">
+        {% block content_descritors_col %}
+
+        {% endblock %}
+    </div>
+</div>
+
+{% endblock %}
+
+{% block resource_block %}
+  	{{ block.super }}
+
+
+{% endblock %}
+
+
diff --git a/projecthandler/template/project/project_graph_base.html b/projecthandler/template/project/project_graph_base.html
new file mode 100644
index 0000000..7d344da
--- /dev/null
+++ b/projecthandler/template/project/project_graph_base.html
@@ -0,0 +1,58 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+  	{{ block.super }}
+    	<link rel="stylesheet" href="{% static "topology3D/css/graph_editor_d3js.css" %}">
+    	<link rel="stylesheet" href="{% static "topology3D/css/d3-context-menu.css" %}">
+{% endblock %}
+{% block title_header_big %}
+    {{ block.super }}
+{% endblock %}
+{% block left_sidebar %}
+
+{% endblock %}
+
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+    <li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview_data.name}}</a></li>
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+ {% csrf_token %}
+<div class="row" >
+    <div class="col-md-12">
+        {% block topology_toolbar %}
+
+
+        {% endblock %}
+        <div id="graph_ed_container" style="width: 100%; height:100%; background-color: white; border: 2px #3c8dbc solid;">
+
+        </div>
+    </div>
+</div>
+
+
+{% endblock %}
+
+{% block resource_block %}
+  	{{ block.super }}
+
+    <!-- d3.js -->
+    <script src="{% static "bower_components/d3/d3.min.js" %}" charset="utf-8"></script>
+
+    <!-- topology3D -->
+    <script src="{% static "topology3D/js/d3-context-menu.js" %}"></script>
+    <script src="{% static "topology3D/js/event.js" %}"></script>
+    <script src="{% static "topology3D/js/graph_editor.js" %}"></script>
+    <script src="{% static "topology3D/js/graph_request.js" %}"></script>
+
+{% endblock %}
+
+
+{% block header %}
+{% endblock %}
+
diff --git a/projecthandler/template/project/projectlist.html b/projecthandler/template/project/projectlist.html
new file mode 100644
index 0000000..5fd3b9d
--- /dev/null
+++ b/projecthandler/template/project/projectlist.html
@@ -0,0 +1,84 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+  	{{ block.super }}
+
+{% endblock %}
+{% block title_header_big %}
+    {{ block.super }}
+{% endblock %}
+{% block left_sidebar %}
+
+{% include 'left_sidebar_base.html' %}
+
+{% endblock %}
+
+
+{% block breadcrumb_body %}
+  	{{ block.super }}
+    <li><a href="{% url 'projects:projects_list' %}">Projects</a></li>
+{% endblock %}
+
+{% block content_body %}
+  	{{ block.super }}
+ {% csrf_token %}
+<div class="row">
+<div class="col-md-12">
+
+    <div class="box">
+        <div class="box-header with-border">
+                  <h3 class="box-title">Projects</h3>
+            <div class="box-tools">
+                <a href="" class="btn btn-block btn-primary btn-sm" disabled><i class="fa fa-plus"></i><span> New Project</span></a>
+            </div>
+        </div>
+        <div class="box-body">
+			<table id="projects_table" class="table table-bordered table-striped">
+				<thead>
+					<tr>
+
+						<th>Name</th>
+						<th>Info</th>
+						<th>Type</th>
+						<th>Modification Date</th>
+						<th>Creation Date</th>
+
+						<th>Owner</th>
+
+						<th><i class="fa fa-trash-o"></i></th>
+					</tr>
+				</thead>
+				<tbody>
+				{% for p in projects %}
+					<tr>
+
+						<td>
+							<a href="javascript:openProject('{{ p.id }}')" >{{ p.name }}</a>
+						</td>
+						<td>{{ p.info }}</td>
+						<td>{{ p.get_type }}</td>
+						<td>{{ p.updated_date }}</td>
+						<td>{{ p.created_date }}</td>
+						<td>{{ p.owner.username }}</td>
+
+						<td><a href="#"> Delete</a></td>
+
+					</tr>
+				{% endfor %}
+				</tbody>
+			</table>
+		</div>
+    </div>
+</div>
+
+</div>
+{% endblock %}
+
+{% block resource_block %}
+  	{{ block.super }}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/projecthandler/template/project/repository/repo_base_left_sidebar.html b/projecthandler/template/project/repository/repo_base_left_sidebar.html
new file mode 100644
index 0000000..3367eeb
--- /dev/null
+++ b/projecthandler/template/project/repository/repo_base_left_sidebar.html
@@ -0,0 +1,12 @@
+{% extends "left_sidebar_base.html" %}
+
+{% block left_sidebar_base %}
+    <li class="header">REPOSITORY</li>
+    {% url "repos:repos_list" as  repo_list_url %}
+    <li {% if request.get_full_path == repo_list_url %} class="active" {% endif %}><a href='{% url "repos:repos_list" %}'><i class="fa fa-git fa-fw"></i><span>Ropository Registered</span></a></li>
+
+    {% block li_list %}
+
+
+    {% endblock %}
+{% endblock %}
diff --git a/projecthandler/template/project/repository/repo_create_modal.html b/projecthandler/template/project/repository/repo_create_modal.html
new file mode 100644
index 0000000..6df53b5
--- /dev/null
+++ b/projecthandler/template/project/repository/repo_create_modal.html
@@ -0,0 +1,43 @@
+<div class="modal" id="modal_new_repository" xmlns="http://www.w3.org/1999/html">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span></button>
+                <h4 class="modal-title" id="modal_new_repo_title">New Repository</h4>
+            </div>
+            <div id="div_chose_id" class="modal-body">
+                <!-- form start -->
+            <form action='{% url "repos:new_repo" %}' class="form-horizontal" role="form" method="post" enctype="multipart/form-data">
+                {% csrf_token %}
+                    <div class="box-body">
+                        <div class="form-group">
+                            <label for="name" class="col-sm-2 control-label">Name</label>
+
+                            <div class="col-sm-10">
+                                <input type="text" class="form-control" id="name" placeholder="Name" name="name" required>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="base_url_repo" class="col-sm-2 control-label">Base Url</label>
+
+                                <div class="col-sm-10">
+                                    <input class="form-control required" id="base_url_repo"
+                                           name="base_url_repo" placeholder="Base Url" pattern="((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?)([\w\.\/\-]*)">
+                                </div>
+                        </div>
+                    </div>
+                    <!-- /.box-body -->
+                    <div class="box-footer">
+                        <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Cancel</button>
+                        <button type="submit" class="btn btn-info pull-right" id="save_new_repo">Register</button>
+                    </div>
+                    <!-- /.box-footer -->
+                </form>
+            </div>
+
+        </div>
+        <!-- /.modal-content -->
+    </div>
+    <!-- /.modal-dialog -->
+</div>
\ No newline at end of file
diff --git a/projecthandler/template/project/repository/repo_list.html b/projecthandler/template/project/repository/repo_list.html
new file mode 100644
index 0000000..1f0a8f3
--- /dev/null
+++ b/projecthandler/template/project/repository/repo_list.html
@@ -0,0 +1,120 @@
+{% extends "base.html" %}
+
+{% load staticfiles %}
+
+{% block head_block %}
+{{ block.super }}
+
+<style type="text/css">
+
+  input:required:invalid, input:focus:invalid {
+
+    background-position: right top;
+    background-repeat: no-repeat;
+  }
+  input:required:valid {
+
+    background-position: right top;
+    background-repeat: no-repeat;
+  }
+
+.form-control.select2-hidden-accessible {
+    top: 30px;
+}
+
+
+</style>
+{% endblock %}
+
+{% block title_header_big %}
+{{ block.super }}
+{% endblock %}
+
+{% block left_sidebar %}
+<!-- Left side column. contains the sidebar -->
+{% include "repository/repo_base_left_sidebar.html" %}
+{% endblock %}
+
+
+{% block breadcrumb_body %}
+{{ block.super }}
+
+{% endblock %}
+
+{% block content_body %}
+{{ block.super }}
+{% csrf_token %}
+    <div class="row">
+
+        <div class="col-md-12">
+
+            <div class="box">
+                <div class="box-header with-border">
+                    <h3 class="box-title">Registered Repository</h3>
+                    <div class="box-tools">
+                        <a href="#" class="btn btn-block btn-primary btn-sm" data-toggle="modal"
+                           data-target="#modal_new_repository"><i
+                                class="fa fa-plus"></i><span> New Repository</span></a>
+                    </div>
+                </div>
+                <div class="box-body">
+                    <table id="deployments_table" class="table table-bordered table-striped">
+                        <thead>
+                        <tr>
+
+                            <th>Name</th>
+                            <th>Url</th>
+                            <th>Last Update</th>
+                            <th>Actions</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        {% for repo in repos %}
+                            <tr>
+
+                                <td>
+                                    {{ repo.name }}
+                                </td>
+                                <td>
+                                    {{ repo.base_url }}
+                                </td>
+                                <td>{{ repo.last_update }}</td>
+                                <td>
+                                    <div class="btn-group">
+                                        <button type="button" class="btn btn-default"><i class="fa fa-cog"
+                                                                                         aria-hidden="true"></i>
+                                        </button>
+                                        <button type="button" class="btn btn-default dropdown-toggle"
+                                                data-toggle="dropdown"
+                                                aria-expanded="false">
+                                            <span class="caret"></span>
+                                            <span class="sr-only">Toggle Dropdown</span>
+                                        </button>
+                                        <ul class="dropdown-menu" role="menu">
+                                            <li class='disabled'><a href='#'><i class="fa fa-edit fa-fw"></i>Edit</a>
+                                            </li>
+                                            <li><a href='{% url "repos:delete_repo" repo_id=repo.id %}'>
+                                                <i class="fa fa-trash fa-fw"></i>Delete</a></li>
+                                        </ul>
+                                    </div>
+                                </td>
+
+                            </tr>
+                        {% endfor %}
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+
+    </div>
+{% include 'repository/repo_create_modal.html' %}
+
+{% endblock %}
+
+{% block resource_block %}
+{{ block.super }}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/projecthandler/tests.py b/projecthandler/tests.py
new file mode 100644
index 0000000..d334413
--- /dev/null
+++ b/projecthandler/tests.py
@@ -0,0 +1,19 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/projecthandler/urls/__init__.py b/projecthandler/urls/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/projecthandler/urls/__init__.py
diff --git a/projecthandler/urls/project.py b/projecthandler/urls/project.py
new file mode 100644
index 0000000..61e4d4e
--- /dev/null
+++ b/projecthandler/urls/project.py
@@ -0,0 +1,54 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from django.conf.urls import url, include
+from projecthandler import views
+
+urlpatterns = [
+    url(r'^list/', views.user_projects, name='projects_list'),
+    url(r'^new/', views.create_new_project, name='new_project'),
+    url(r'^(?P<project_id>\d+)/$', views.open_project, name='open_project'),
+    url(r'^(?P<project_id>\d+)/instances/', include('instancehandler.urls', namespace='instances'), name='instances_base'),
+    url(r'^(?P<project_id>\d+)/delete$', views.delete_project, name='delete_project'),
+    url(r'^(?P<project_id>\d+)/graph(/$)', views.graph, name='graph_view'),
+    url(r'^(?P<project_id>\d+)/graph/graph_data(/$)', views.graph_data, name='graph_data'),
+    url(r'^(?P<project_id>\d+)/graph/graph_data/(?P<descriptor_id>[-\w]+)(/$)', views.graph_data, name='graph_data'),
+    url(r'^(?P<project_id>\d+)/graph/positions$', views.graph_positions, name='graph_positions'),
+    url(r'^(?P<project_id>\d+)/graph/unusedvnf/(?P<nsd_id>\w+)(/$)', views.unused_vnf, name='unused_vnf'),
+    url(r'^(?P<project_id>\d+)/graph/addelement$', views.add_element, name='addelement'),
+    url(r'^(?P<project_id>\d+)/graph/overviewelement$', views.overviewelement, name='overviewelement'),
+    url(r'^(?P<project_id>\d+)/graph/addnodetovnffg', views.add_node_to_vnffg, name='addnodetovnffg'),
+    url(r'^(?P<project_id>\d+)/graph/removeelement$', views.remove_element, name='removeelement'),
+    url(r'^(?P<project_id>\d+)/graph/addlink$', views.add_link, name='addlink'),
+    url(r'^(?P<project_id>\d+)/graph/removelink$', views.remove_link, name='removelink'),
+    url(r'^(?P<project_id>\d+)/graph/availablenodes', views.get_available_nodes, name='get_available_nodes'),
+    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)(/$)', views.show_descriptors, name='list_descriptors'),
+    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)(/$)',
+        views.edit_descriptor, name='edit_descriptor'),
+    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/delete$',
+        views.delete_descriptor,
+        name='delete_descriptor'),
+    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/clone$',
+        views.clone_descriptor,
+        name='clone_descriptor'),
+    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/action/(?P<action_name>[-\w]+)',
+        views.custom_action,
+        name='custom_action'),
+    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/new$', views.new_descriptor,
+        name='new_descriptor'),
+
+
+]
\ No newline at end of file
diff --git a/projecthandler/views.py b/projecthandler/views.py
new file mode 100644
index 0000000..8c553a4
--- /dev/null
+++ b/projecthandler/views.py
@@ -0,0 +1,537 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import json
+
+from django.contrib.auth.decorators import login_required
+from django.http import HttpResponse, JsonResponse
+from django.middleware.csrf import get_token
+from django.shortcuts import render, redirect
+from django.template.loader import render_to_string
+from lib.util import Util
+from sf_user.models import CustomUser
+import tarfile
+
+
+from projecthandler.osm_model import OsmProject
+from projecthandler.models import Project
+
+
+Project.add_project_type('osm', OsmProject)
+
+
+
+from projecthandler.models import Repository
+
+@login_required
+def home(request):
+    return render(request, 'home.html', {})
+
+
+@login_required
+def create_new_project(request):
+    if request.method == 'POST':
+        error_msgs = []
+        user = CustomUser.objects.get(id=request.user.id)
+        name = request.POST.get('name', 'WithoutName')
+        info = request.POST.get('info', ' ')
+        type = request.POST.get('type', '')
+        start_from = request.POST.get('startfrom', 'scratch')
+
+        project_types = Project.get_project_types()
+        if type in project_types:
+            project_class = project_types[type]
+
+        else:
+            # FIXME this error is not handled
+            error_msgs.append('Project type undefined.')
+            return render(request, 'error.html',
+                          {'error_msg': 'Error creating new project, project type undefined. Please retry.'})
+
+        try:
+
+            if start_from == 'scratch':
+                print 'from scratch'
+                data_project = {}
+
+            elif start_from == 'files':
+                print 'from files'
+                data_project = project_class.data_project_from_files(request)
+
+            elif start_from == 'example':
+                print 'from example'
+                data_project = project_class.data_project_from_example(request)
+
+            project = project_class.create_project(name, user, False, info, data_project)
+            # print project.get_dataproject()
+
+
+        except Exception as e:
+            print 'Error creating ' + type + ' project! Please retry.'
+            print e
+            return render(request, 'error.html', {'error_msg': 'Error creating ' + type + ' project! Please retry.'})
+        return redirect('projects:open_project', project_id=project.id)
+
+    elif request.method == 'GET':
+        csrf_token_value = get_token(request)
+        result = {}
+        data_type_selector = [{
+            'id': '-1',
+            'text': 'Select an option'
+        }]
+        type_example_files = {}
+        type_container_template = ''
+        project_types = Project.get_project_types()
+        print "project_types", project_types.keys()
+        for type in project_types:
+            project_class = project_types[type]
+            type_example_files.update(project_class.get_example_list())
+            data_type_selector.append({
+                'id': type,
+                'text': type,
+                'value': type
+            })
+            type_container_template += render_to_string(type + '/' + type + '_new_project.html')
+
+        result.update({'type_example_files': json.dumps(type_example_files)})
+        result.update({'data_type_selector': json.dumps(data_type_selector)})
+        result.update({'type_container_template': type_container_template})
+        result.update({'csrf_token': csrf_token_value})
+        return render(request, 'new_project.html', result)
+
+
+@login_required
+def user_projects(request):
+    csrf_token_value = get_token(request)
+    user = CustomUser.objects.get(id=request.user.id)
+    projects = Project.objects.filter(owner=user).select_subclasses()
+
+    return render(request, 'projectlist.html', {
+        'projects': list(projects),
+        'csrf_token': csrf_token_value
+    })
+
+
+@login_required
+def open_project(request, project_id=None):
+    try:
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        project_overview = projects[0].get_overview_data()
+        prj_token = project_overview['type']
+        print request.COOKIES.keys()
+        return render(request, prj_token + '/' + prj_token + '_project_details.html',
+                      {'project_overview': project_overview, 'project_id': project_id})
+
+    except Exception as e:
+        print e
+        return render(request, 'error.html', {'error_msg': 'Error open project! Please retry.'})
+
+
+@login_required
+def delete_project(request, project_id=None):
+    if request.method == 'POST':
+
+        try:
+            Project.objects.filter(id=project_id).delete()
+            return redirect('projects:projects_list')
+        except Exception as e:
+            print e
+            return render(request, 'error.html', {'error_msg': 'Error deleting Project.'})
+
+    elif request.method == 'GET':
+        try:
+            projects = Project.objects.filter(id=project_id).select_subclasses()
+            project_overview = projects[0].get_overview_data()
+            prj_token = project_overview['type']
+            #                 example: 'etsi/etsi_project_delete.html'
+            print  prj_token + '/' + prj_token + '_project_delete.html', project_overview['name']
+            return render(request, prj_token + '/' + prj_token + '_project_delete.html',
+                          {'project_id': project_id, 'project_name': project_overview['name']})
+
+        except Exception as e:
+            print e
+            return render(request, 'error.html', {'error_msg': 'Project not found.'})
+
+
+
+@login_required
+def show_descriptors(request, project_id=None, descriptor_type=None):
+    csrf_token_value = get_token(request)
+    projects = Project.objects.filter(id=project_id).select_subclasses()
+    project_overview = projects[0].get_overview_data()
+    prj_token = project_overview['type']
+
+    page = prj_token + '/' + prj_token + '_project_descriptors.html'
+
+    return render(request, page, {
+        'descriptors': projects[0].get_descriptors(descriptor_type),
+        'project_id': project_id,
+        'project_type': prj_token,
+        'project_overview_data': project_overview,
+        "csrf_token_value": csrf_token_value,
+        'descriptor_type': descriptor_type
+    })
+
+
+@login_required
+def graph(request, project_id=None):
+    if request.method == 'GET':
+        csrf_token_value = get_token(request)
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        project_overview = projects[0].get_overview_data()
+        prj_token = project_overview['type']
+        # example : 'etsi/project_graph.html'
+        return render(request, prj_token + '/project_graph.html', {
+            'project_id': project_id,
+            'project_overview_data': projects[0].get_overview_data(),
+            'collapsed_sidebar': False
+        })
+
+
+@login_required
+def graph_data(request, project_id=None, descriptor_id=None):
+    print 'graph_data', project_id, descriptor_id
+    projects = Project.objects.filter(id=project_id).select_subclasses()
+    project_overview = projects[0].get_overview_data()
+    # data = projects[0].get_overview_data()
+    prj_token = project_overview['type']
+
+    topology = projects[0].get_graph_data_json_topology(descriptor_id)
+    response = HttpResponse(topology, content_type="application/json")
+    response["Access-Control-Allow-Origin"] = "*"
+
+    return response
+
+
+@login_required
+def delete_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
+    csrf_token_value = get_token(request)
+    projects = Project.objects.filter(id=project_id).select_subclasses()
+    result = projects[0].delete_descriptor(descriptor_type, descriptor_id)
+    project_overview = projects[0].get_overview_data()
+    prj_token = project_overview['type']
+    page = prj_token + '/' + prj_token + '_project_descriptors.html'
+
+    return render(request, page, {
+        'descriptors': projects[0].get_descriptors(descriptor_type),
+        'project_id': project_id,
+        'project_overview_data': project_overview,
+        "csrf_token_value": csrf_token_value,
+        'descriptor_type': descriptor_type,
+        #'alert_message': {
+        #    'success': result,
+        #    'message': "Delete succeeded!" if result else 'Error in delete'}
+    })
+
+
+@login_required
+def clone_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
+    csrf_token_value = get_token(request)
+    projects = Project.objects.filter(id=project_id).select_subclasses()
+    new_id = request.GET.get('newid', '')
+    result = projects[0].clone_descriptor(descriptor_type, descriptor_id, new_id)
+    project_overview = projects[0].get_overview_data()
+    prj_token = project_overview['type']
+    page = prj_token + '/' + prj_token + '_project_descriptors.html'
+
+    return render(request, page, {
+        'descriptors': projects[0].get_descriptors(descriptor_type),
+        'project_id': project_id,
+        'project_overview_data': project_overview,
+        "csrf_token_value": csrf_token_value,
+        'descriptor_type': descriptor_type,
+        'alert_message': {
+            'success': result,
+            'message': "Cloned!" if result else 'Error in cloning'}
+    })
+
+
+@login_required
+def new_descriptor(request, project_id=None, descriptor_type=None):
+    projects = Project.objects.filter(id=project_id).select_subclasses()
+    project_overview = projects[0].get_overview_data()
+    prj_token = project_overview['type']
+    page = prj_token + '/descriptor/descriptor_new.html'
+    if request.method == 'GET':
+        request_id = request.GET.get('id', '')
+
+        json_template = projects[0].get_new_descriptor(descriptor_type, request_id)
+        print 'new descriptor GET', json_template
+
+        descriptor_string_yaml = Util.json2yaml(json_template)
+        descriptor_string_json = json.dumps(json_template)
+
+        return render(request, page, {
+            'project_id': project_id,
+            'descriptor_type': descriptor_type,
+            'descriptor_id': request_id,
+            'project_overview_data': project_overview,
+            'descriptor_strings': {'descriptor_string_yaml': descriptor_string_yaml,
+                                   'descriptor_string_json': descriptor_string_json}
+        })
+    elif request.method == 'POST':
+        csrf_token_value = get_token(request)
+        data_type = request.POST.get('type')
+        print "TYPE", data_type
+        if data_type == "file":
+            file_uploaded = request.FILES['file']
+            text = file_uploaded.read()
+            data_type = file_uploaded.name.split(".")[-1]
+            desc_name = file_uploaded.name.split(".")[0]
+            result = projects[0].create_descriptor(desc_name, descriptor_type, text, data_type, file_uploaded)
+        else:
+            text = request.POST.get('text')
+            desc_name = request.POST.get('id')
+            result = projects[0].create_descriptor(desc_name, descriptor_type, text, data_type)
+
+
+        response_data = {
+            'project_id': project_id,
+            'descriptor_type': descriptor_type,
+            'project_overview_data': projects[0].get_overview_data(),
+            'descriptor_id': result,
+            'alert_message': {
+                'success': True if result != False else False,
+                'message': "Descriptor created" if result else 'Error in creation'}
+        }
+        status_code = 200 if result != False else 500
+        response = HttpResponse(json.dumps(response_data), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+
+@login_required
+def edit_descriptor(request, project_id=None, descriptor_id=None, descriptor_type=None):
+    if request.method == 'POST':
+        print "edit_descriptor"
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].edit_descriptor(descriptor_type, descriptor_id, request.POST.get('text'),
+                                             request.POST.get('type'))
+        response_data = {
+            'project_id': project_id,
+            'descriptor_type': descriptor_type,
+            #'project_overview_data': projects[0].get_overview_data(),
+            'alert_message': {
+                'success':  True if result else False,
+                'message': "Descriptor modified." if result else 'Error during descriptor editing.'}
+        }
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps(response_data), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+    elif request.method == 'GET':
+        csrf_token_value = get_token(request)
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        project_overview = projects[0].get_overview_data()
+        print project_overview
+        prj_token = project_overview['type']
+        page = prj_token + '/descriptor/descriptor_view.html'
+
+        descriptor = projects[0].get_descriptor(descriptor_id, descriptor_type)
+
+        descriptor_string_json = json.dumps(descriptor)
+        descriptor_string_yaml = Util.json2yaml(descriptor)
+        # print descriptor
+        return render(request, page, {
+            'project_id': project_id,
+            'descriptor_id': descriptor_id,
+            'project_overview_data': projects[0].get_overview_data(),
+            'descriptor_type': descriptor_type,
+            'descriptor_strings': {'descriptor_string_yaml': descriptor_string_yaml,
+                                   'descriptor_string_json': descriptor_string_json}})
+
+
+@login_required
+def graph_positions(request, project_id=None):
+    if request.method == 'POST':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].edit_graph_positions(json.loads(request.POST.get('positions')))
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+
+@login_required
+def add_element(request, project_id=None):
+    if request.method == 'POST':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].get_add_element(request)
+
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+
+@login_required
+def remove_element(request, project_id=None):
+    if request.method == 'POST':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].get_remove_element(request)
+
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+
+@login_required
+def add_link(request, project_id=None):
+    if request.method == 'POST':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].get_add_link(request)
+
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+
+@login_required
+def remove_link(request, project_id=None):
+    if request.method == 'POST':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].get_remove_link(request)
+
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+@login_required
+def get_available_nodes(request, project_id=None):
+    if request.method == 'GET':
+        csrf_token_value = get_token(request)
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        print "get_available_nodes", request.GET.dict()
+        result = projects[0].get_available_nodes(request.GET.dict())
+        status_code = 500 if result == None else 200
+        print json.dumps(result)
+        response = HttpResponse(json.dumps(result), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+@login_required
+def overviewelement(request, project_id=None):
+    if request.method == 'GET':
+        result = {}
+        error_msg = None
+        try:
+            projects = Project.objects.filter(id=project_id).select_subclasses()
+            project = projects[0]
+            parameters = request.GET.dict()
+            print "parameters", parameters
+            result = project.get_node_overview(**parameters)
+        except Exception as e:
+            error_msg = str(e)
+
+        if error_msg is not None:
+            return JsonResponse({'error': {'error_msg': str(error_msg)}})
+
+        return JsonResponse({'node_overview': result})
+
+# ETSI specific method #
+@login_required
+def add_node_to_vnffg(request, project_id=None):
+    print "add_node_to_vnffg"  # TODO log
+    if request.method == 'POST':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].add_node_to_vnffg(request)
+
+        status_code = 200 if result else 500
+        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+
+@login_required
+def unused_vnf(request, project_id=None, nsd_id=None):
+    if request.method == 'GET':
+        print 'in method unused_vnf : ', project_id, nsd_id  # TODO log
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        result = projects[0].get_unused_vnf(nsd_id)
+        status_code = 500 if result == None else 200
+        response = HttpResponse(json.dumps(result), content_type="application/json", status=status_code)
+        response["Access-Control-Allow-Origin"] = "*"
+        return response
+
+# end ETSI specific method #
+
+
+# OSM specific method #
+def get_package_files_list(request, project_id, project, descriptor_id, descriptor_type):
+    files_list = []
+    try:
+        files_list = project.get_package_files_list(descriptor_type, descriptor_id)
+        result = {'files': files_list}
+    except Exception as e:
+        print e
+        url = 'error.html'
+        result = {'error_msg': 'Unknown error.'}
+    return __response_handler(request, result)
+
+
+def download_pkg(request, project_id, project, descriptor_id, descriptor_type):
+    tar_pkg = project.download_pkg(project, descriptor_id, descriptor_type)
+
+    response = HttpResponse(content_type="application/tgz")
+    response["Content-Disposition"] = "attachment; filename=osm_export.tar.gz"
+    response.write(tar_pkg.getvalue())
+    return response
+
+
+def create_ns(request, project_id, project, descriptor_id, descriptor_type):
+    files_list = []
+    try:
+        ns_data={
+          "nsName": request.POST.get('nsName', 'WithoutName'),
+          "nsDescription": request.POST.get('nsDescription', ''),
+          "nsdId": request.POST.get('nsdId', ''),
+          "vimAccountId": request.POST.get('vimAccountId', ''),
+          "ssh-authorized-key": [
+            {
+              request.POST.get('key-pair-ref', ''): request.POST.get('keyValue', '')
+            }
+          ]
+        }
+        #result = project.create_ns(descriptor_type, descriptor_id, ns_data)
+
+    except Exception as e:
+        print e
+        url = 'error.html'
+        result = {'error_msg': 'Unknown error.'}
+    return __response_handler(request, result)
+
+# end OSM specific method #
+
+@login_required
+def custom_action(request, project_id=None, descriptor_id=None, descriptor_type=None, action_name=None):
+    if request.method == 'GET':
+        projects = Project.objects.filter(id=project_id).select_subclasses()
+        print "Custom action: " + action_name
+        return globals()[action_name](request, project_id, projects[0], descriptor_id, descriptor_type)
+
+
+def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
+    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
+    if 'application/json' in raw_content_types:
+        return JsonResponse(data_res)
+    elif to_redirect:
+        return redirect(url, *args, **kwargs)
+    else:
+        return render(request, url, data_res)