X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=rwlaunchpad%2Fplugins%2Frwpkgmgr%2Frift%2Ftasklets%2Frwpkgmgr%2Fdownloader%2Fcopy.py;h=671501d1a82780d302793b3201e81a471efbf778;hb=f314b4af9744068a7ed7a6a6314220c3aa857523;hp=c64a3f597257c9545bab951ba5323cab9fd06eba;hpb=64ad3e11038417cd3f8faec4f4695edb292ae2c2;p=osm%2FSO.git diff --git a/rwlaunchpad/plugins/rwpkgmgr/rift/tasklets/rwpkgmgr/downloader/copy.py b/rwlaunchpad/plugins/rwpkgmgr/rift/tasklets/rwpkgmgr/downloader/copy.py index c64a3f59..671501d1 100644 --- a/rwlaunchpad/plugins/rwpkgmgr/rift/tasklets/rwpkgmgr/downloader/copy.py +++ b/rwlaunchpad/plugins/rwpkgmgr/rift/tasklets/rwpkgmgr/downloader/copy.py @@ -16,12 +16,13 @@ # Author(s): Nandan Sinha # +import enum +import gi +import json import os -import uuid import shutil -import enum +import uuid -import gi gi.require_version('RwVnfdYang', '1.0') gi.require_version('RwNsdYang', '1.0') from gi.repository import ( @@ -34,6 +35,7 @@ from gi.repository import ( ) import rift.package.icon as icon +import rift.tasklets.rwlaunchpad.onboard as onboard class PackageCopyError(Exception): pass @@ -69,12 +71,35 @@ class CopyMeta: return self.__dict__ def to_yang(self): - job = RwPkgMgmtYang.CopyJob.from_dict({ + job = RwPkgMgmtYang.YangData_RwProject_Project_CopyJobs_Job.from_dict({ "transaction_id": self.transaction_id, "status": CopyMeta.STATUS_MAP[self.state] }) return job +class CopyManifest: + """ Utility class to hold manifest information.""" + def __init__(self, project, log): + self.tasklet_info = project.tasklet.tasklet_info + self.manifest = self.tasklet_info.get_pb_manifest() + self.use_ssl = self.manifest.bootstrap_phase.rwsecurity.use_ssl + self.ssl_cert, self.ssl_key = None, None + if self.use_ssl: + self.ssl_cert = self.manifest.bootstrap_phase.rwsecurity.cert + self.ssl_key = self.manifest.bootstrap_phase.rwsecurity.key + self.onboarder = None + self.log = log + + def ssl_manifest(self): + return (self.use_ssl, self.ssl_cert, self.ssl_key) + + def get_onboarder(self, host="127.0.0.1", port="8008"): + if not self.onboarder: + self.onboarder = onboard.DescriptorOnboarder(self.log, + host, port, *self.ssl_manifest()) + return self.onboarder + + class PackageFileCopier: DESCRIPTOR_MAP = { "vnfd": (RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd, 'vnfd rw-vnfd'), @@ -82,11 +107,13 @@ class PackageFileCopier: } @classmethod - def from_rpc_input(cls, rpc_input, proxy, log=None): + def from_rpc_input(cls, rpc_input, project, proxy, log=None): return cls( rpc_input.package_id, rpc_input.package_type, rpc_input.package_name, + rpc_input.project_name, + project = project, proxy = proxy, log=log) @@ -94,11 +121,15 @@ class PackageFileCopier: pkg_id, pkg_type, pkg_name, + proj_name, + project, proxy, log): self.src_package_id = pkg_id self.package_type = pkg_type.lower() self.dest_package_name = pkg_name + self.project_name = proj_name + self.manifest = CopyManifest(project, log) self.dest_package_id = str(uuid.uuid4()) self.transaction_id = str(uuid.uuid4()) self.proxy = proxy @@ -107,17 +138,27 @@ class PackageFileCopier: self.src_package = None self.dest_desc_msg = None + @property + def onboarder(self): + """ Onboarder object to invoke REST endpoint calls.""" + return self.manifest.get_onboarder() + + @property + def progress(self): + """ Current status of operations.""" + return self.meta.to_yang() + + @property + def descriptor_msg(self): + """ Descriptor message of the generated copied descriptor.""" + return self.dest_desc_msg + # Start of delegate calls def call_delegate(self, event): if not self.delegate: return - # Send out the descriptor message to be posted on success - # Otherwise send out the CopyJob yang conversion from meta object. - if event == "on_download_succeeded": - getattr(self.delegate, event)(self.dest_desc_msg) - else: - getattr(self.delegate, event)(self.meta.to_yang()) + getattr(self.delegate, event)(self) def _copy_tree(self): """ @@ -127,12 +168,13 @@ class PackageFileCopier: """ self.copy_progress() - store = self.proxy._get_store(self.package_type) + store = self.proxy._get_store(self.package_type, \ + self.project_name if self.project_name else None) src_path = store._get_package_dir(self.src_package_id) self.src_package = store.get_package(self.src_package_id) self.dest_copy_path = os.path.join( - store.DEFAULT_ROOT_DIR, + store.root_dir, self.dest_package_id) self.log.debug("Copying contents from {src} to {dest}". format(src=src_path, dest=self.dest_copy_path)) @@ -154,29 +196,43 @@ class PackageFileCopier: def _create_descriptor_file(self): """ Update descriptor file for the newly copied descriptor catalog. - Use the existing descriptor file to create a descriptor proto gi object, - change some identifiers, and create a new descriptor yaml file from it. - + Get descriptor contents from REST endpoint, change some identifiers + and create a new descriptor yaml file from it. """ - src_desc_file = self.src_package.descriptor_file - src_desc_contents = self.src_package.descriptor_msg.as_dict() - src_desc_contents.update( + # API call for the updated descriptor contents + src_desc_contents = self.onboarder.get_updated_descriptor(self.src_package.descriptor_msg, self.project_name) + + # To generate the pb object, extract subtree in dict from "project-nsd:nsd" and root it + # under "nsd:nsd-catalog" (or vnfd) + root_element = "{0}:{0}-catalog".format(self.package_type) + extract_sub_element = "project-{0}:{0}".format(self.package_type, self.package_type) + src_desc_contents[extract_sub_element].update( id =self.dest_package_id, name = self.dest_package_name, short_name = self.dest_package_name ) + D = {} + D[root_element] = {self.package_type : src_desc_contents[extract_sub_element]} + # Build the proto-buf gi object from generated JSON + json_desc_msg = json.dumps(D) + self.log.debug("*** JSON contents: {}".format(json_desc_msg)) desc_cls, modules = PackageFileCopier.DESCRIPTOR_MAP[self.package_type] - self.dest_desc_msg = desc_cls.from_dict(src_desc_contents) - dest_desc_path = os.path.join(self.dest_copy_path, - "{pkg_name}_{pkg_type}.yaml".format(pkg_name=self.dest_package_name, pkg_type=self.package_type)) - model = RwYang.Model.create_libncx() + + model = RwYang.Model.create_libyang() for module in modules.split(): model.load_module(module) + self.dest_desc_msg = desc_cls.from_json(model, json_desc_msg, strict=False) + + # Write to yaml desc file + dest_desc_path = os.path.join(self.dest_copy_path, + "{pkg_name}_{pkg_type}.yaml".format(pkg_name=self.dest_package_name, pkg_type=self.package_type)) with open(dest_desc_path, "w") as fh: fh.write(self.dest_desc_msg.to_yaml(model)) + # Remove copied .yaml, if present + src_desc_file = self.src_package.descriptor_file copied_desc_file = os.path.join(self.dest_copy_path, os.path.basename(src_desc_file)) if os.path.exists(copied_desc_file): self.log.debug("Deleting copied yaml from old source %s" % (copied_desc_file))