From 9ccf7d0ba2132b34df4b70fec183c03911344707 Mon Sep 17 00:00:00 2001 From: lombardofr Date: Tue, 27 Nov 2018 17:03:10 +0100 Subject: [PATCH] bug fix on NSD composer; enabling button compose new descriptor Change-Id: I2b50eee0e2a2c20823abf51e2fb0d40c3e1e13ff Signed-off-by: lombardofr --- .../template/descriptorlist.html | 10 +- .../template/modal/choose_node_id.html | 1 - .../template/modal/choose_package_name.html | 35 +++++ descriptorhandler/urls.py | 4 +- descriptorhandler/views.py | 27 +++- lib/osm/osm_util.py | 2 +- lib/osm/osmclient/clientv2.py | 133 +++++++++++++++--- .../project/osm/osm_project_descriptors.html | 33 +++++ 8 files changed, 211 insertions(+), 34 deletions(-) delete mode 100644 descriptorhandler/template/modal/choose_node_id.html create mode 100644 descriptorhandler/template/modal/choose_package_name.html diff --git a/descriptorhandler/template/descriptorlist.html b/descriptorhandler/template/descriptorlist.html index 5285125..bbe8f21 100644 --- a/descriptorhandler/template/descriptorlist.html +++ b/descriptorhandler/template/descriptorlist.html @@ -7,12 +7,10 @@

- {% comment %}
- -
{% endcomment %} +
+ +
diff --git a/descriptorhandler/template/modal/choose_node_id.html b/descriptorhandler/template/modal/choose_node_id.html deleted file mode 100644 index 91c4d20..0000000 --- a/descriptorhandler/template/modal/choose_node_id.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "descriptor/modal/choose_node_id.html" %} \ No newline at end of file diff --git a/descriptorhandler/template/modal/choose_package_name.html b/descriptorhandler/template/modal/choose_package_name.html new file mode 100644 index 0000000..2211026 --- /dev/null +++ b/descriptorhandler/template/modal/choose_package_name.html @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/descriptorhandler/urls.py b/descriptorhandler/urls.py index b0972d9..481211a 100644 --- a/descriptorhandler/urls.py +++ b/descriptorhandler/urls.py @@ -19,9 +19,9 @@ from descriptorhandler import views urlpatterns = [ url(r'(?P\w+)/list$', views.show_descriptors, name='list_descriptors'), + url(r'(?P\w+)/create', views.create_package_empty, name='create_package_empty'), url(r'(?P\w+)/(?P[-\w]+)(/$)', views.edit_descriptor, name='edit_descriptor'), - url(r'(?P\w+)/(?P[-\w]+)/delete$', views.delete_descriptor, - name='delete_descriptor'), + url(r'(?P\w+)/(?P[-\w]+)/delete$', views.delete_descriptor, name='delete_descriptor'), url(r'(?P\w+)/(?P[-\w]+)/clone', views.clone_descriptor, name='clone_descriptor'), url(r'(?P\w+)/(?P[-\w]+)/addElement/(?P\w+)', views.addElement, name='addElement'), diff --git a/descriptorhandler/views.py b/descriptorhandler/views.py index 064b5a5..fda9aff 100644 --- a/descriptorhandler/views.py +++ b/descriptorhandler/views.py @@ -90,12 +90,35 @@ def delete_descriptor(request, descriptor_type=None, descriptor_id=None): 'message': 'An error occurred while processing your request.' if result and result['error'] is True else "Record deleted successfully"} }, url) +@login_required +def create_package_empty(request, descriptor_type=None): + user = osmutils.get_user(request) + pkg_name = request.POST.get('name', '') + try: + client = Client() + if descriptor_type == 'nsd': + result = client.nsd_create_pkg_base(user.get_token(), pkg_name) + elif descriptor_type == 'vnfd': + result = client.vnfd_create_pkg_base(user.get_token(), pkg_name) + 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)} + + if result['error'] == True: + return __response_handler(request, result['data'], url=None, + status=result['data']['status'] if 'status' in result['data'] else 500) + else: + result['data']['type'] = descriptor_type + return __response_handler(request, result, url=None, status=200) + @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': @@ -111,7 +134,6 @@ def clone_descriptor(request, descriptor_type=None, descriptor_id=None): 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) @@ -319,7 +341,6 @@ def edit_descriptor(request, descriptor_id=None, descriptor_type=None): result = client.nsd_get(user.get_token(), descriptor_id) elif descriptor_type == 'vnfd': result = client.vnfd_get(user.get_token(), descriptor_id) - except Exception as e: log.exception(e) result = {'error': True, 'data': str(e)} diff --git a/lib/osm/osm_util.py b/lib/osm/osm_util.py index 8cf6a4e..7e536cb 100644 --- a/lib/osm/osm_util.py +++ b/lib/osm/osm_util.py @@ -116,7 +116,7 @@ class OsmUtil(): indexes = [] for cvnfd in nsd['constituent-vnfd']: indexes.append(int(cvnfd["member-vnf-index"])) - memberindex = max(indexes) + 1 + memberindex = max(indexes) + 1 if len(indexes) > 0 else 1 nsd['constituent-vnfd'].append({ "member-vnf-index": memberindex, "vnfd-id-ref": element_id diff --git a/lib/osm/osmclient/clientv2.py b/lib/osm/osmclient/clientv2.py index 414019e..8fbb0d2 100644 --- a/lib/osm/osmclient/clientv2.py +++ b/lib/osm/osmclient/clientv2.py @@ -13,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - +import errno import requests import logging -import json import tarfile import yaml -import pyaml import StringIO from lib.util import Util import hashlib @@ -32,6 +30,7 @@ logging.basicConfig(level=logging.INFO) log = logging.getLogger('helper.py') logging.getLogger("urllib3").setLevel(logging.INFO) + class Client(object): def __init__(self): self._token_endpoint = 'admin/v1/tokens' @@ -329,7 +328,7 @@ class Client(object): _url = "{0}/nsd/v1/ns_descriptors_content/{1}".format(self._base_path, id) try: - r = requests.delete(_url, params=None, verify=False,headers=headers) + r = requests.delete(_url, params=None, verify=False, headers=headers) except Exception as e: log.exception(e) result['data'] = str(e) @@ -361,13 +360,13 @@ class Client(object): result = {'error': True, 'data': ''} headers = {"Content-Type": "application/gzip", "accept": "application/json", 'Authorization': 'Bearer {}'.format(token['id'])} - with open('/tmp/'+package.name, 'wb+') as destination: + with open('/tmp/' + package.name, 'wb+') as destination: for chunk in package.chunks(): destination.write(chunk) - headers['Content-File-MD5'] = self.md5(open('/tmp/'+package.name, 'rb')) + headers['Content-File-MD5'] = self.md5(open('/tmp/' + package.name, 'rb')) _url = "{0}/nsd/v1/ns_descriptors_content/".format(self._base_path) try: - r = requests.post(_url, data=open('/tmp/'+package.name, 'rb'), verify=False, headers=headers) + r = requests.post(_url, data=open('/tmp/' + package.name, 'rb'), verify=False, headers=headers) except Exception as e: log.exception(e) result['data'] = str(e) @@ -381,13 +380,13 @@ class Client(object): result = {'error': True, 'data': ''} headers = {"Content-Type": "application/gzip", "accept": "application/json", 'Authorization': 'Bearer {}'.format(token['id'])} - with open('/tmp/'+package.name, 'wb+') as destination: + with open('/tmp/' + package.name, 'wb+') as destination: for chunk in package.chunks(): destination.write(chunk) - headers['Content-File-MD5'] = self.md5(open('/tmp/'+package.name, 'rb')) + headers['Content-File-MD5'] = self.md5(open('/tmp/' + package.name, 'rb')) _url = "{0}/vnfpkgm/v1/vnf_packages_content".format(self._base_path) try: - r = requests.post(_url, data=open('/tmp/'+package.name, 'rb'), verify=False, headers=headers) + r = requests.post(_url, data=open('/tmp/' + package.name, 'rb'), verify=False, headers=headers) except Exception as e: log.exception(e) result['data'] = str(e) @@ -397,6 +396,48 @@ class Client(object): result['data'] = Util.json_loads_byteified(r.text) return result + def nsd_create_pkg_base(self, token, pkg_name): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/gzip", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/nsd/v1/ns_descriptors_content/".format(self._base_path) + + try: + self._create_base_pkg('nsd', pkg_name) + r = requests.post(_url, data=open('/tmp/' + pkg_name + '.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['data'] = r.json() + result['error'] = False + if r.status_code == requests.codes.conflict: + result['data'] = "Invalid ID." + return result + + def vnfd_create_pkg_base(self, token, pkg_name): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/gzip", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/vnfpkgm/v1/vnf_packages_content".format(self._base_path) + + try: + self._create_base_pkg('vnfd', pkg_name) + r = requests.post(_url, data=open('/tmp/' + pkg_name + '.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['data'] = r.json() + result['error'] = False + if r.status_code == requests.codes.conflict: + result['data'] = "Invalid ID." + return result + def nsd_clone(self, token, id): result = {'error': True, 'data': ''} headers = {"Content-Type": "application/gzip", "accept": "application/json", @@ -412,7 +453,7 @@ class Client(object): try: r = requests.post(_url, data=open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", 'rb'), verify=False, - headers=headers) + headers=headers) except Exception as e: log.exception(e) result['data'] = str(e) @@ -440,7 +481,7 @@ class Client(object): try: r = requests.post(_url, data=open('/tmp/' + tarf.getnames()[0] + "_clone.tar.gz", 'rb'), verify=False, - headers=headers) + headers=headers) except Exception as e: log.exception(e) result['data'] = str(e) @@ -506,7 +547,7 @@ class Client(object): def get_nsd_pkg(self, token, id): result = {'error': True, 'data': ''} - headers = { "accept": "application/zip", + headers = {"accept": "application/zip", 'Authorization': 'Bearer {}'.format(token['id'])} _url = "{0}/nsd/v1/ns_descriptors/{1}/nsd_content".format(self._base_path, id) @@ -556,6 +597,59 @@ class Client(object): tarf_temp.close() return tarf + def _create_base_pkg(self, descriptor_type, pkg_name): + filename = '/tmp/'+pkg_name+'/' + pkg_name + '.yaml' + if descriptor_type == 'nsd': + descriptor = { + "nsd:nsd-catalog": { + "nsd": [ + { + "short-name": str(pkg_name), + "vendor": "OSM Composer", + "description": str(pkg_name) + " descriptor", + "vld": [], + "constituent-vnfd": [], + "version": "1.0", + "id": str(pkg_name), + "name": str(pkg_name) + } + ] + } + } + + elif descriptor_type == 'vnfd': + descriptor = { + "vnfd:vnfd-catalog": { + "vnfd": [ + { + "short-name": str(pkg_name), + "vdu": [], + "description": "", + "mgmt-interface": {}, + "id": str(pkg_name), + "version": "1.0", + "internal-vld": [], + "connection-point": [], + "name": str(pkg_name) + } + ] + } + } + + if not os.path.exists(os.path.dirname(filename)): + try: + os.makedirs(os.path.dirname(filename)) + except OSError as exc: # Guard against race condition + if exc.errno != errno.EEXIST: + raise + + with open('/tmp/' + pkg_name + '/' + pkg_name + '.yaml', 'w') as yaml_file: + yaml_file.write(yaml.dump(descriptor, default_flow_style=False)) + + tarf_temp = tarfile.open('/tmp/' + pkg_name + '.tar.gz', "w:gz") + tarf_temp.add('/tmp/'+pkg_name+'/' + pkg_name + '.yaml', pkg_name + '/' + pkg_name + '.yaml', recursive=False) + tarf_temp.close() + def _descriptor_clone(self, tarf, descriptor_type): # extract the package on a tmp directory tarf.extractall('/tmp') @@ -569,8 +663,8 @@ class Client(object): 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'] + 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: @@ -578,7 +672,6 @@ class Client(object): 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 @@ -815,7 +908,7 @@ class Client(object): return result if r.status_code == requests.codes.ok: result['error'] = False - #result['data'] = Util.json_loads_byteified(r.text) + # result['data'] = Util.json_loads_byteified(r.text) result['data'] = r.text return result @@ -832,7 +925,7 @@ class Client(object): return result if r.status_code == requests.codes.ok: result['error'] = False - #result['data'] = Util.json_loads_byteified(r.text) + # result['data'] = Util.json_loads_byteified(r.text) result['data'] = r.text return result @@ -855,7 +948,7 @@ class Client(object): def vim_delete(self, token, id): result = {'error': True, 'data': ''} - headers = { "accept": "application/json", + headers = {"accept": "application/json", 'Authorization': 'Bearer {}'.format(token['id'])} _url = "{0}/admin/v1/vims/{1}".format(self._base_path, id) try: @@ -957,7 +1050,6 @@ class Client(object): result['data'] = Util.json_loads_byteified(r.text) return result - def sdn_create(self, token, sdn_data): result = {'error': True, 'data': ''} headers = {"Content-Type": "application/json", "accept": "application/json", @@ -976,7 +1068,6 @@ class Client(object): result['data'] = Util.json_loads_byteified(r.text) return result - @staticmethod def md5(f): hash_md5 = hashlib.md5() diff --git a/projecthandler/template/project/osm/osm_project_descriptors.html b/projecthandler/template/project/osm/osm_project_descriptors.html index 2491bf0..bf40773 100644 --- a/projecthandler/template/project/osm/osm_project_descriptors.html +++ b/projecthandler/template/project/osm/osm_project_descriptors.html @@ -35,6 +35,7 @@ {{ block.super }} {% include 'osm/modal/files_list.html' %} {% include 'modal/instance_create.html' %} +{% include 'modal/choose_package_name.html' %}
{% include "descriptorlist.html" %}
@@ -158,7 +159,39 @@ }); setInterval(refreshTable, 10000); + + + $("#formCreatePackage").submit(function (event) { + event.preventDefault(); //prevent default action + var post_url = $(this).attr("action"); //get form action url + var request_method = $(this).attr("method"); + var form_data = new FormData(this); //Encode form elements for submission + + $.ajax({ + url: post_url, + type: request_method, + data: form_data, + headers: { + "Accept": 'application/json' + }, + contentType: false, + processData: false + }).done(function (response, textStatus, jqXHR) { + + location.href='/projects/descriptors/composer?type=' + response['data']['type']+'&id=' + response['data']['id']; + }).fail(function (result) { + var data = result.responseJSON; + var title = "Error " + (data.code ? data.code : 'unknown'); + var message = data.detail ? data.detail : 'No detail available.'; + bootbox.alert({ + title: title, + message: message + }); + }); + }); }); + + -- 2.25.1