clone packages 65/6465/2
authorlombardofr <lombardo@everyup.it>
Mon, 10 Sep 2018 14:55:15 +0000 (16:55 +0200)
committerlombardofr <lombardo@everyup.it>
Tue, 11 Sep 2018 13:18:59 +0000 (15:18 +0200)
Change-Id: Iefe34dc4309ebc53cdee6f2d59924e10ea72e487
Signed-off-by: lombardofr <lombardo@everyup.it>
lib/osm/osmclient/clientv2.py
projecthandler/template/project/osm/descriptor/descriptorlist.html
projecthandler/template/project/osm/osm_project_descriptors.html
projecthandler/urls/project.py
projecthandler/views.py
static/src/projecthandler/descriptorslist.js

index feb710c..482ff07 100644 (file)
@@ -102,7 +102,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
@@ -190,7 +189,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
@@ -210,7 +208,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.no_content:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.no_content:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
@@ -379,6 +376,61 @@ class Client(object):
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
+    def nsd_clone(self, token, id):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/gzip", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+
+        # get the package onboarded
+        tar_pkg = self.get_nsd_pkg(token, id)
+        tarf = tarfile.open(fileobj=tar_pkg)
+        tarf = self._descriptor_clone(tarf, 'nsd')
+        headers['Content-File-MD5'] = self.md5(open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", 'rb'))
+
+        _url = "{0}/nsd/v1/ns_descriptors_content/".format(self._base_path)
+
+        try:
+            r = requests.post(_url, data=open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", 'rb'), verify=False,
+                             headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.created:
+            result['error'] = False
+        if r.status_code == requests.codes.conflict:
+            result['data'] = "Invalid ID."
+
+        return result
+
+    def vnfd_clone(self, token, id):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/gzip", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+
+        # get the package onboarded
+        tar_pkg = self.get_vnfd_pkg(token, id)
+        tarf = tarfile.open(fileobj=tar_pkg)
+
+        tarf = self._descriptor_clone(tarf, 'vnfd')
+        headers['Content-File-MD5'] = self.md5(open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", 'rb'))
+
+        _url = "{0}/vnfpkgm/v1/vnf_packages_content".format(self._base_path)
+
+        try:
+            r = requests.post(_url, data=open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", 'rb'), verify=False,
+                             headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.created:
+            result['error'] = False
+        if r.status_code == requests.codes.conflict:
+            result['data'] = "Invalid ID."
+
+        return result
+
     def nsd_update(self, token, id, data):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/gzip", "accept": "application/json",
     def nsd_update(self, token, id, data):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/gzip", "accept": "application/json",
@@ -456,7 +508,6 @@ class Client(object):
         _url = "{0}/vnfpkgm/v1/vnf_packages/{1}/package_content".format(self._base_path, id)
         try:
             r = requests.get(_url, params=None, verify=False, stream=True, headers=headers)
         _url = "{0}/vnfpkgm/v1/vnf_packages/{1}/package_content".format(self._base_path, id)
         try:
             r = requests.get(_url, params=None, verify=False, stream=True, headers=headers)
-            print r.status_code
         except Exception as e:
             log.exception(e)
             result['data'] = str(e)
         except Exception as e:
             log.exception(e)
             result['data'] = str(e)
@@ -468,7 +519,6 @@ class Client(object):
         return result
 
     def _descriptor_update(self, tarf, data):
         return result
 
     def _descriptor_update(self, tarf, data):
-        print tarf.getnames()
         # extract the package on a tmp directory
         tarf.extractall('/tmp')
 
         # extract the package on a tmp directory
         tarf.extractall('/tmp')
 
@@ -479,14 +529,43 @@ class Client(object):
                 break
 
         tarf_temp = tarfile.open('/tmp/' + tarf.getnames()[0] + ".tar.gz", "w:gz")
                 break
 
         tarf_temp = tarfile.open('/tmp/' + tarf.getnames()[0] + ".tar.gz", "w:gz")
-        # tarf_temp = tarfile.open("pippo.tar.gz", "w:gz")
-        print tarf_temp.getnames()
-        # tarf_temp.add('/tmp/'+tarf.getnames()[0])
+
+        for tarinfo in tarf:
+            tarf_temp.add('/tmp/' + tarinfo.name, tarinfo.name, recursive=False)
+        tarf_temp.close()
+        return tarf
+
+    def _descriptor_clone(self, tarf, descriptor_type):
+        # extract the package on a tmp directory
+        tarf.extractall('/tmp')
+
+        for name in tarf.getnames():
+            if name.endswith(".yaml") or name.endswith(".yml"):
+                with open('/tmp/' + name, 'r') as outfile:
+                    yaml_object = yaml.load(outfile)
+
+                    if descriptor_type == 'nsd':
+                        nsd_list = yaml_object['nsd:nsd-catalog']['nsd']
+                        for nsd in nsd_list:
+                            nsd['id'] = 'clone_' + nsd['id']
+                            nsd['name'] = 'clone_' +nsd['name']
+                            nsd['short-name'] = 'clone_' +nsd['short-name']
+                    elif descriptor_type == 'vnfd':
+                        vnfd_list = yaml_object['vnfd:vnfd-catalog']['vnfd']
+                        for vnfd in vnfd_list:
+                            vnfd['id'] = 'clone_' + vnfd['id']
+                            vnfd['name'] = 'clone_' + vnfd['name']
+                            vnfd['short-name'] = 'clone_' + vnfd['short-name']
+
+
+                    with open('/tmp/' + name, 'w') as yaml_file:
+                        yaml_file.write(yaml.dump(yaml_object, default_flow_style=False))
+                break
+
+        tarf_temp = tarfile.open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", "w:gz")
+
         for tarinfo in tarf:
         for tarinfo in tarf:
-            # if tarinfo.name.startswith(tarf.getnames()[0]):
-            #    new_name = tarinfo.name[len(tarf.getnames()[0]):]
             tarf_temp.add('/tmp/' + tarinfo.name, tarinfo.name, recursive=False)
             tarf_temp.add('/tmp/' + tarinfo.name, tarinfo.name, recursive=False)
-        print tarf_temp.getnames()
         tarf_temp.close()
         return tarf
 
         tarf_temp.close()
         return tarf
 
@@ -643,7 +722,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
@@ -714,7 +792,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.ok:
             result['error'] = False
         #result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.ok:
             result['error'] = False
         #result['data'] = Util.json_loads_byteified(r.text)
@@ -732,7 +809,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.ok:
             result['error'] = False
         #result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.ok:
             result['error'] = False
         #result['data'] = Util.json_loads_byteified(r.text)
@@ -767,7 +843,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.accepted:
             result['error'] = False
         else:
         if r.status_code == requests.codes.accepted:
             result['error'] = False
         else:
@@ -806,7 +881,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
@@ -839,7 +913,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.accepted:
             result['error'] = False
         else:
         if r.status_code == requests.codes.accepted:
             result['error'] = False
         else:
@@ -877,7 +950,6 @@ class Client(object):
             log.exception(e)
             result['data'] = str(e)
             return result
             log.exception(e)
             result['data'] = str(e)
             return result
-        print r.status_code
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
         if r.status_code == requests.codes.created:
             result['error'] = False
         result['data'] = Util.json_loads_byteified(r.text)
index 734259f..b2222e2 100644 (file)
                 </tr>
                 </thead>
                 <tbody>
                 </tr>
                 </thead>
                 <tbody>
-                {% for k in descriptors %}
-                    <tr role="row">
-                        <td>{{ k|get:"short-name" }} </td>
-                        <td>{{ k|get:"_id" }}</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':'{{ project_id }}', 'descriptor_type': '{{ descriptor_type }}', 'descriptor_name':'{{ k|get:"name" }}', 'descriptor_id':'{{ k|get:"_id" }}','vim_list_url': '{% url "vims:list"  %}',  'nsd_list_url': '{% url "projects:list_descriptors"  descriptor_type=descriptor_type %}' })">
-                                        <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('{{ 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('{{ 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/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'  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( '{{ descriptor_type }}', '{{ k|get:"_id" }}')">
-                                    <i class="far fa-trash-alt"></i></button>
-                            </div>
 
 
-                        </td>
-                    </tr>
-                {% endfor %}
                 </tbody>
 
             </table>
                 </tbody>
 
             </table>
index 182c8cc..4478ade 100644 (file)
@@ -76,7 +76,7 @@
             "columns": [
                 {
                     "render": function (data, type, row) {
             "columns": [
                 {
                     "render": function (data, type, row) {
-                       return row['short-name'];
+                       return row['short-name'] || '';
                     },
                     "targets": 0
                 },
                     },
                     "targets": 0
                 },
                            '        data-toggle="tooltip" data-placement="top" title="Show content"\n' +
                            '        onclick="javascript:openPackageContentList(\''+ descriptor_type +'\', \''+row["_id"]+'\')">\n' +
                            '    <i class="fa fa-folder-open"></i></button>\n' +
                            '        data-toggle="tooltip" data-placement="top" title="Show content"\n' +
                            '        onclick="javascript:openPackageContentList(\''+ descriptor_type +'\', \''+row["_id"]+'\')">\n' +
                            '    <i class="fa fa-folder-open"></i></button>\n' +
+                            '<button type="button" class="btn btn-default" data-container="body"\n' +
+                           '        data-toggle="tooltip" data-placement="top" title="Clone"\n' +
+                           '        onclick="javascript:clonePackage(\''+ descriptor_type +'\', \''+row["_id"]+'\')">\n' +
+                           '    <i class="fa fa-clone"></i></button>\n' +
                            '<button type="button" class="btn btn-default" data-container="body"\n' +
                            '        data-toggle="tooltip" data-placement="top" title="Show Graph"\n' +
                            '        onclick="location.href=\'/projects/graph?type='+descriptor_type+'&id='+row["_id"] +'\'"\n' +
                            '<button type="button" class="btn btn-default" data-container="body"\n' +
                            '        data-toggle="tooltip" data-placement="top" title="Show Graph"\n' +
                            '        onclick="location.href=\'/projects/graph?type='+descriptor_type+'&id='+row["_id"] +'\'"\n' +
                            '    <i class="fa fa-download fa-fw"></i></button>\n' +
                            '<button type="button" class="btn btn-default" data-container="body"\n' +
                            '        data-toggle="tooltip" data-placement="top" title="Delete"\n' +
                            '    <i class="fa fa-download fa-fw"></i></button>\n' +
                            '<button type="button" class="btn btn-default" data-container="body"\n' +
                            '        data-toggle="tooltip" data-placement="top" title="Delete"\n' +
-                           '        onclick="javascript:deletePackage( \'' + descriptor_type + '\', \''+row["_id"] + '\')">\n' +
+                           '        onclick="javascript:deletePackage( \'' + descriptor_type + '\', \''+row["_id"] + '\', \''+row["name"] + '\')">\n' +
                            '    <i class="far fa-trash-alt"></i></button>\n' +
                            '</div>';
 
                            '    <i class="far fa-trash-alt"></i></button>\n' +
                            '</div>';
 
index 9d653b6..91c79c7 100644 (file)
@@ -30,6 +30,9 @@ urlpatterns = [
     url(r'^descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/delete$',
         views.delete_descriptor,
         name='delete_descriptor'),
     url(r'^descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/delete$',
         views.delete_descriptor,
         name='delete_descriptor'),
+    url(r'^descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/clone',
+        views.clone_descriptor,
+        name='clone_descriptor'),
     url(r'^descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/action/(?P<action_name>[-\w]+)',
         views.custom_action,
         name='custom_action'),
     url(r'^descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/action/(?P<action_name>[-\w]+)',
         views.custom_action,
         name='custom_action'),
index 06b4770..1f1573d 100644 (file)
@@ -376,6 +376,32 @@ def delete_descriptor(request, descriptor_type=None, descriptor_id=None):
     }, url)
 
 
     }, url)
 
 
+@login_required
+def clone_descriptor(request, descriptor_type=None, descriptor_id=None):
+    user = osmutils.get_user(request)
+    project_id = user.project_id
+
+    try:
+        client = Client()
+        if descriptor_type == 'nsd':
+            result = client.nsd_clone(user.get_token(), descriptor_id)
+        elif descriptor_type == 'vnfd':
+            result = client.vnfd_clone(user.get_token(), descriptor_id)
+        else:
+            log.debug('Update descriptor: Unknown data type')
+            result = {'error': True, 'data': 'Update descriptor: Unknown data type'}
+    except Exception as e:
+        log.exception(e)
+        result = {'error': True, 'data': str(e)}
+    print result
+    if result['error'] == True:
+        return __response_handler(request, result['data'], url=None,
+                                  status=result['data']['status'] if 'status' in result['data'] else 500)
+
+    else:
+        return __response_handler(request, {}, url=None, status=200)
+
+
 
 @login_required
 def new_descriptor(request, descriptor_type=None):
 
 @login_required
 def new_descriptor(request, descriptor_type=None):
index c85603c..bf31480 100644 (file)
@@ -1,6 +1,6 @@
-function deletePackage(descriptor_type, package_id) {
+function deletePackage(descriptor_type, package_id, package_name) {
 
 
-    bootbox.confirm("Are you sure want to delete?", function (result) {
+    bootbox.confirm("Are you sure want to delete " + package_name + "?", function (result) {
         if (result) {
             var dialog = bootbox.dialog({
                 message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
         if (result) {
             var dialog = bootbox.dialog({
                 message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
@@ -24,6 +24,32 @@ function deletePackage(descriptor_type, package_id) {
     })
 }
 
     })
 }
 
+function clonePackage(descriptor_type, package_id) {
+
+    bootbox.confirm("Are you sure want to clone?", function (result) {
+        if (result) {
+            var dialog = bootbox.dialog({
+                message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
+                closeButton: true
+            });
+            $.ajax({
+                url: '/projects/descriptors/' + descriptor_type + '/' + package_id + '/clone',
+                type: 'GET',
+                dataType: "json",
+                contentType: "application/json;charset=utf-8",
+                success: function (result) {
+                    dialog.modal('hide');
+                    location.reload();
+                },
+                error: function (result) {
+                    dialog.modal('hide');
+                    bootbox.alert("An error occurred.");
+                }
+            });
+        }
+    })
+}
+
 
 function openPackageContentList(type, pkg_id) {
     var dialog = bootbox.dialog({
 
 function openPackageContentList(type, pkg_id) {
     var dialog = bootbox.dialog({