Example #1
0
def load_from_file(archive_path, target_dir=None, drop_dir=False):
    if not os.path.isfile(archive_path):
        raise e.PackageLoadError('Unable to find package file')
    created = False
    if not target_dir:
        target_dir = tempfile.mkdtemp()
        created = True
    elif not os.path.exists(target_dir):
        os.mkdir(target_dir)
        created = True
    else:
        if os.listdir(target_dir):
            raise e.PackageLoadError('Target directory is not empty')

    try:
        if not zipfile.is_zipfile(archive_path):
            raise e.PackageFormatError("Uploaded file {0} is not a "
                                       "zip archive".format(archive_path))
        package = zipfile.ZipFile(archive_path)
        package.extractall(path=target_dir)
        yield load_from_dir(target_dir)
    except ValueError as err:
        raise e.PackageLoadError("Couldn't load package from file: "
                                 "{0}".format(err))
    finally:
        if drop_dir:
            if created:
                shutil.rmtree(target_dir)
            else:
                for f in os.listdir(target_dir):
                    os.unlink(os.path.join(target_dir, f))
Example #2
0
def load_from_dir(source_directory, filename='manifest.yaml'):
    if not os.path.isdir(source_directory) or not os.path.exists(
            source_directory):
        raise e.PackageLoadError('Invalid package directory')
    full_path = path.secure_join(source_directory, filename)
    if not os.path.isfile(full_path):
        raise e.PackageLoadError('Unable to find package manifest')

    try:
        with open(full_path) as stream:
            content = yaml.safe_load(stream)
    except Exception as ex:
        trace = sys.exc_info()[2]
        utils.reraise(
            e.PackageLoadError,
            e.PackageLoadError("Unable to load due to '{0}'".format(ex)),
            trace)
    else:
        format_spec = str(content.get('Format') or 'MuranoPL/1.0')
        if format_spec[0].isdigit():
            format_spec = 'MuranoPL/' + format_spec
        plugin_loader = get_plugin_loader()
        handler = plugin_loader.get_package_handler(format_spec)
        if handler is None:
            raise e.PackageFormatError(
                'Unsupported format {0}'.format(format_spec))
        return handler(source_directory, content)
Example #3
0
    def _translate_class(self):
        template_file = os.path.join(self._source_directory, 'template.yaml')
        shutil.copy(template_file, self.get_resource(self.full_name))

        if not os.path.isfile(template_file):
            raise exceptions.PackageClassLoadError(
                self.full_name, 'File with class definition not found')
        with open(template_file) as stream:
            hot = yaml.safe_load(stream)
            if 'resources' not in hot:
                raise exceptions.PackageFormatError('Not a HOT template')
        translated = {
            'Name': self.full_name,
            'Extends': 'io.murano.Application'
        }

        hot_envs_path = os.path.join(self._source_directory,
                                     RESOURCES_DIR_NAME, HOT_ENV_DIR_NAME)

        # if using hot environments, doing parameter validation with contracts
        # will overwrite the parameters in the hot environment.
        # don't validate parameters if hot environments exist.
        validate_hot_parameters = (not os.path.isdir(hot_envs_path)
                                   or not os.listdir(hot_envs_path))

        parameters = HotPackage._build_properties(hot, validate_hot_parameters)
        parameters.update(HotPackage._translate_outputs(hot))
        translated['Properties'] = parameters

        files = HotPackage._translate_files(self._source_directory)
        translated.update(HotPackage._generate_workflow(hot, files))
        self._translated_class = yaml.dump(translated, Dumper=Dumper)
Example #4
0
def load_from_dir(source_directory,
                  filename='manifest.yaml',
                  preload=False,
                  loader=yaql_yaml_loader.YaqlYamlLoader):
    formats = {
        '1.0': murano.packages.versions.mpl_v1,
        'MuranoPL/1.0': murano.packages.versions.mpl_v1,
        'Heat.HOT/1.0': murano.packages.versions.hot_v1
    }

    if not os.path.isdir(source_directory) or not os.path.exists(
            source_directory):
        raise e.PackageLoadError('Invalid package directory')
    full_path = os.path.join(source_directory, filename)
    if not os.path.isfile(full_path):
        raise e.PackageLoadError('Unable to find package manifest')

    try:
        with open(full_path) as stream:
            content = yaml.safe_load(stream)
    except Exception as ex:
        trace = sys.exc_info()[2]
        raise e.PackageLoadError("Unable to load due to '{0}'".format(
            str(ex))), None, trace
    if content:
        p_format = str(content.get('Format'))
        if not p_format or p_format not in formats:
            raise e.PackageFormatError('Unknown or missing format version')
        package = formats[p_format].create(source_directory, content, loader)
        formats[p_format].load(package, content)
        if preload:
            package.validate()
        return package
Example #5
0
def load_from_file(archive_path,
                   target_dir=None,
                   drop_dir=False,
                   loader=yaql_yaml_loader.YaqlYamlLoader):
    if not os.path.isfile(archive_path):
        raise e.PackageLoadError('Unable to find package file')
    created = False
    if not target_dir:
        target_dir = tempfile.mkdtemp()
        created = True
    elif not os.path.exists(target_dir):
        os.mkdir(target_dir)
        created = True
    else:
        if os.listdir(target_dir):
            raise e.PackageLoadError('Target directory is not empty')

    try:
        if not zipfile.is_zipfile(archive_path):
            raise e.PackageFormatError("Uploading file should be a "
                                       "zip' archive")
        package = zipfile.ZipFile(archive_path)
        package.extractall(path=target_dir)
        return load_from_dir(target_dir, preload=True, loader=loader)
    finally:
        if drop_dir:
            if created:
                shutil.rmtree(target_dir)
            else:
                for f in os.listdir(target_dir):
                    os.unlink(os.path.join(target_dir, f))
 def _check_full_name(full_name):
     error = exceptions.PackageFormatError('Invalid FullName ' + full_name)
     if re.match(r'^[\w\.]+$', full_name):
         if full_name.startswith('.') or full_name.endswith('.'):
             raise error
         if '..' in full_name:
             raise error
     else:
         raise error
Example #7
0
def load_from_dir(source_directory, filename='manifest.yaml'):
    formats = {
        'MuranoPL': {
            ('1.0.0', '1.0.0'): murano.packages.mpl_package.MuranoPlPackage,
        },
        'Heat.HOT': {
            ('1.0.0', '1.0.0'): murano.packages.hot_package.HotPackage
        }
    }

    if not os.path.isdir(source_directory) or not os.path.exists(
            source_directory):
        raise e.PackageLoadError('Invalid package directory')
    full_path = os.path.join(source_directory, filename)
    if not os.path.isfile(full_path):
        raise e.PackageLoadError('Unable to find package manifest')

    try:
        with open(full_path) as stream:
            content = yaml.safe_load(stream)
    except Exception as ex:
        trace = sys.exc_info()[2]
        raise e.PackageLoadError("Unable to load due to '{0}'".format(
            str(ex))), None, trace
    if content:
        p_format_spec = str(content.get('Format') or 'MuranoPL/1.0')
        if p_format_spec[0] in string.digits:
            p_format_spec = 'MuranoPL/' + p_format_spec
        parts = p_format_spec.split('/', 1)
        if parts[0] not in formats:
            raise e.PackageFormatError('Unknown or missing format version')
        format_set = formats[parts[0]]
        version = semantic_version.Version('0.0.0')
        if len(parts) > 1:
            version = semantic_version.Version.coerce(parts[1])
        for key, value in format_set.iteritems():
            min_version = semantic_version.Version(key[0])
            max_version = semantic_version.Version(key[1])
            if min_version <= version <= max_version:
                return value(source_directory, content, parts[0], version)
        raise e.PackageFormatError('Unsupported {0} format version {1}'.format(
            parts[0], version))
 def test_package_format_error(self):
     messages = ['', 'test_message']
     for message in messages:
         error = exceptions.PackageFormatError(message=message)
         expected = 'Incorrect package format'
         if message:
             expected += ': {0}'.format(message)
         if six.PY2:
             self.assertEqual(expected, error.message)
         elif six.PY34:
             self.assertEqual(expected, error.args[0])
Example #9
0
    def __init__(self, source_directory, manifest, package_format,
                 runtime_version):
        super(PackageBase, self).__init__(source_directory, package_format,
                                          runtime_version)
        self._full_name = manifest.get('FullName')
        if not self._full_name:
            raise exceptions.PackageFormatError('FullName is not specified')
        self._check_full_name(self._full_name)
        self._version = semantic_version.Version.coerce(
            str(manifest.get('Version', '0.0.0')))
        self._package_type = manifest.get('Type')
        if self._package_type not in package.PackageType.ALL:
            raise exceptions.PackageFormatError(
                'Invalid package Type {0}'.format(self._package_type))
        self._display_name = manifest.get('Name', self._full_name)
        self._description = manifest.get('Description')
        self._author = manifest.get('Author')
        self._supplier = manifest.get('Supplier') or {}
        self._logo = manifest.get('Logo')
        self._tags = manifest.get('Tags')

        self._logo_cache = None
        self._supplier_logo_cache = None
Example #10
0
def load(package, yaml_content):
    package._full_name = yaml_content.get('FullName')
    if not package._full_name:
        raise murano.packages.exceptions.PackageFormatError(
            'FullName not specified')
    _check_full_name(package._full_name)
    package._package_type = yaml_content.get('Type')
    if not package._package_type or package._package_type not in \
            murano.packages.application_package.PackageTypes.ALL:
        raise e.PackageFormatError('Invalid Package Type')
    package._display_name = yaml_content.get('Name', package._full_name)
    package._description = yaml_content.get('Description')
    package._author = yaml_content.get('Author')
    package._supplier = yaml_content.get('Supplier') or {}
    package._logo = yaml_content.get('Logo')
    package._tags = yaml_content.get('Tags')
Example #11
0
    def _translate_class(self):
        csar_file = os.path.join(self._source_directory, 'csar.zip')
        shutil.copy(csar_file, self.get_resource(self.full_name))

        if not os.path.isfile(csar_file):
            raise exceptions.PackageClassLoadError(
                self.full_name, 'File with class definition not found')

        csar_obj = csar.CSAR(csar_file)
        try:
            csar_obj.validate()
        except csar_exception.ValidationError as ve:
            raise exceptions.PackageFormatError('Not a CSAR archive: ' +
                                                str(ve))

        translated = {
            'Name': self.full_name,
            'Extends': 'io.murano.Application'
        }

        csar_envs_path = os.path.join(self._source_directory,
                                      CSAR_RESOURCES_DIR_NAME,
                                      CSAR_ENV_DIR_NAME)

        validate_csar_parameters = (not os.path.isdir(csar_envs_path)
                                    or not os.listdir(csar_envs_path))

        tosca = csar_obj.get_main_template_yaml()
        parameters = CSARPackage._build_properties(tosca,
                                                   validate_csar_parameters)
        parameters.update(CSARPackage._translate_outputs(tosca))
        translated['Properties'] = parameters
        hot = yaml.load(
            self._translate('tosca', csar_obj.csar, parameters, True))
        files = CSARPackage._translate_files(self._source_directory)

        template_file = os.path.join(self._source_directory,
                                     CSAR_RESOURCES_DIR_NAME, 'template.yaml')
        with open(template_file, 'w') as outfile:
            outfile.write(yaml.safe_dump(hot))
        translated.update(CSARPackage._generate_workflow(hot, files))
        self._translated_class = yaml.dump(translated,
                                           Dumper=Dumper,
                                           default_style='"')
Example #12
0
    def _translate_class(self):
        template_file = path.secure_join(self._source_directory,
                                         'template.yaml')

        if not os.path.isfile(template_file):
            raise exceptions.PackageClassLoadError(
                self.full_name, 'File with class definition not found')

        shutil.copy(template_file, self.get_resource(self.full_name))
        with open(template_file) as stream:
            hot = yaml.safe_load(stream)
            if 'resources' not in hot:
                raise exceptions.PackageFormatError('Not a HOT template')
        translated = {
            'Name': self.full_name,
            'Extends': 'io.murano.Application'
        }

        hot_envs_path = path.secure_join(self._source_directory,
                                         RESOURCES_DIR_NAME, HOT_ENV_DIR_NAME)

        # if using hot environments, doing parameter validation with contracts
        # will overwrite the parameters in the hot environment.
        # don't validate parameters if hot environments exist.
        validate_hot_parameters = (not os.path.isdir(hot_envs_path)
                                   or not os.listdir(hot_envs_path))

        parameters = HotPackage._build_properties(hot, validate_hot_parameters)
        parameters.update(HotPackage._translate_outputs(hot))
        translated['Properties'] = parameters

        files = HotPackage._translate_files(self._source_directory)
        translated.update(HotPackage._generate_workflow(hot, files))

        # use default_style with double quote mark because by default PyYAML
        # doesn't put any quote marks ans as a result strings with e.g. dashes
        # may be interpreted as YAQL expressions upon load
        self._translated_class = yaml.dump(translated,
                                           Dumper=Dumper,
                                           default_style='"')