[RIFT 16413, 16414] Unittest failures fixed for utest_package, utest_publisher_dts
[osm/SO.git] / rwlaunchpad / plugins / rwlaunchpadtasklet / rift / package / package.py
index 45d8ba8..2859b1b 100644 (file)
@@ -1,5 +1,5 @@
 
-# 
+#
 #   Copyright 2016 RIFT.IO Inc
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,6 +42,10 @@ class PackageValidationError(Exception):
     pass
 
 
+class PackageAppendError(Exception):
+    pass
+
+
 class PackageFileChecksumError(PackageValidationError):
     def __init__(self, filename):
         self.filename = filename
@@ -157,6 +161,26 @@ class DescriptorPackage(object):
 
         return self.descriptor_msg.id
 
+    @property
+    def descriptor_name(self):
+        """  The descriptor name of this descriptor in the system """
+        if not self.descriptor_msg.has_field("name"):
+            msg = "Descriptor name not present"
+            self._log.error(msg)
+            raise PackageError(msg)
+
+        return self.descriptor_msg.name
+
+    @property
+    def descriptor_version(self):
+        desc_msg = self.descriptor_msg
+        return desc_msg.version if desc_msg.has_field("version") else ''
+
+    @property
+    def descriptor_vendor(self):
+        desc_msg = self.descriptor_msg
+        return desc_msg.vendor if desc_msg.has_field("vendor") else ''
+
     @classmethod
     def get_descriptor_patterns(cls):
         """ Returns a tuple of descriptor regex and Package Types  """
@@ -333,6 +357,42 @@ class DescriptorPackage(object):
                     # Set the file mode to original
                     os.chmod(dest_file_path, self._package_file_mode_map[filename])
 
+    def insert_file(self, new_file, dest_file, rel_path, mode=0o777):
+        self.add_file(rel_path, mode)
+
+        try:
+            # Copy the contents of the file to the correct path
+            # For folder creation (or nested folders), dest_file appears w/ trailing "/" like: dir1/ or dir1/dir2/
+            # For regular file upload, dest_file appears as dir1/abc.txt
+
+            dest_dir_path = os.path.dirname(dest_file)
+            if not os.path.isdir(dest_dir_path):
+                os.makedirs(dest_dir_path)
+                if not os.path.basename(dest_file): 
+                    self._log.debug("Created dir path, no filename to insert in {}, skipping..".format(dest_dir_path))
+                    return
+
+            with open(dest_file, 'wb') as dst_hdl:
+                with open(new_file, 'rb') as src_hdl:
+                    shutil.copyfileobj(src_hdl, dst_hdl, 10 * 1024 * 1024)
+
+                    # Set the file mode to original
+                    os.chmod(dest_file, self._package_file_mode_map[rel_path])
+        except Exception as e:
+            # Clear the file when an exception happens
+            if os.path.isfile(dest_file):
+                os.remove(dest_file)
+
+            raise PackageAppendError(str(e))
+
+    def delete_file(self, dest_file, rel_path):
+        self.remove_file(rel_path)
+
+        try:
+            os.remove(dest_file)
+        except Exception as e:
+            raise PackageAppendError(str(e))
+
     def extract_file(self, src_file, dest_file):
         """ Extract a specific package file to dest_file
 
@@ -428,6 +488,15 @@ class DescriptorPackage(object):
 
         self._package_file_mode_map[rel_path] = mode
 
+    def remove_file(self, rel_path):
+        if not rel_path:
+            raise PackageError("Empty file name added")
+
+        if rel_path not in self._package_file_mode_map:
+            raise PackageError("File %s does not exist in package" % rel_path)
+
+        del self._package_file_mode_map[rel_path]
+
     def add_dir(self, rel_path):
         """ Add a directory to the package
 
@@ -472,6 +541,32 @@ class VnfdPackage(DescriptorPackage):
     def serializer(self):
         return VnfdPackage.SERIALIZER
 
+class PackageConstructValidator(object): 
+
+    def __init__(self, log):
+        self._log = log
+
+    def validate(self, package):
+        """ Validate presence of descriptor file (.yaml) at the top level in the 
+        package folder structure. 
+
+        Arguments: 
+            package - The Descriptor Package being validated. 
+        Returns: 
+            None
+        Raises:
+            PackageValidationError - The package validation failed for some
+              generic reason.
+        """
+        pass
+        desc_file = package.descriptor_file
+        prefix, desc_file = package.prefix.rstrip('/'), desc_file.rstrip('/')
+
+        if os.path.dirname(desc_file) != prefix: 
+            msg = "Descriptor file {} not found in expcted location {}".format(desc_file, prefix)
+            self._log.error(msg)
+            raise PackageValidationError(msg)
+
 
 class PackageChecksumValidator(object):
     """  This class uses the checksums.txt file in the package
@@ -482,6 +577,7 @@ class PackageChecksumValidator(object):
 
     def __init__(self, log):
         self._log = log
+        self.validated_file_checksums = {}
 
     @classmethod
     def get_package_checksum_file(cls, package):
@@ -491,6 +587,10 @@ class PackageChecksumValidator(object):
 
         return checksum_file
 
+    @property
+    def checksums(self):
+        return self.validated_file_checksums
+
     def validate(self, package):
         """ Validate file checksums match that in the checksums.txt
 
@@ -506,7 +606,6 @@ class PackageChecksumValidator(object):
             PackageFileChecksumError - A file within the package did not match the
               checksum within checksums.txt
         """
-        validated_file_checksums = {}
 
         try:
             checksum_file = PackageChecksumValidator.get_package_checksum_file(package)
@@ -514,7 +613,7 @@ class PackageChecksumValidator(object):
                 archive_checksums = checksums.ArchiveChecksums.from_file_desc(checksum_hdl)
         except (FileNotFoundError, PackageError) as e:
             self._log.warning("Could not open package checksum file.  Not validating checksums.")
-            return validated_file_checksums
+            return self.validated_file_checksums
 
         for pkg_file in package.files:
             if pkg_file == checksum_file:
@@ -542,9 +641,7 @@ class PackageChecksumValidator(object):
                 self._log.error(msg)
                 raise PackageFileChecksumError(pkg_file)
 
-            validated_file_checksums[pkg_file] = file_checksum
-
-        return validated_file_checksums
+            self.validated_file_checksums[pkg_file] = file_checksum
 
 
 class TarPackageArchive(object):