628b30fc2c
Tool was run against murano-apps catalog, all found bugs was fixed Change-Id: I7b31d6d3adff749126cbafdfbc2a45aa6d16c24a
156 lines
6.7 KiB
Python
156 lines
6.7 KiB
Python
# Copyright (c) 2016 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
import os.path
|
|
|
|
import semantic_version
|
|
import six
|
|
|
|
from muranopkgcheck import consts
|
|
from muranopkgcheck import error
|
|
from muranopkgcheck.i18n import _
|
|
from muranopkgcheck.validators import base
|
|
from muranopkgcheck import yaml_loader
|
|
|
|
error.register.E030(description='Not supported format')
|
|
error.register.E050(description='File is present in Manifest, '
|
|
'but not in filesystem')
|
|
error.register.E070(description='Tags should be a list')
|
|
error.register.E071(description='Type is invalid')
|
|
error.register.E072(description='UI is not a string')
|
|
error.register.E073(description='Invalid FullName')
|
|
error.register.E074(description='Logo is not a string')
|
|
error.register.W020(description='File is not present in Manifest, '
|
|
'but it is in filesystem')
|
|
error.register.W030(description='Not supported format version')
|
|
error.register.W073(description='There is no UI file')
|
|
error.register.W074(description='There is no Logo file')
|
|
|
|
|
|
class ManifestValidator(base.YamlValidator):
|
|
def __init__(self, loaded_package):
|
|
super(ManifestValidator, self).__init__(loaded_package,
|
|
'manifest.yaml$')
|
|
self.add_checker(self._valid_format, 'Format', False)
|
|
self.add_checker(self._valid_string, 'Author', False)
|
|
self.add_checker(self._valid_version, 'Version', False)
|
|
self.add_checker(self._valid_fullname, 'FullName')
|
|
self.add_checker(self._valid_string, 'Name', False)
|
|
self.add_checker(self._valid_classes, 'Classes', False)
|
|
self.add_checker(self._valid_tags, 'Tags', False)
|
|
self.add_checker(self._valid_require, 'Require', False)
|
|
self.add_checker(self._valid_type, 'Type')
|
|
self.add_checker(self._valid_description, 'Description')
|
|
self.add_checker(self._valid_ui, 'UI', False)
|
|
self.add_checker(self._valid_logo, 'Logo', False)
|
|
self.add_checker(self._valid_logo_ui_existance)
|
|
|
|
def _valid_description(self, desc):
|
|
if not isinstance(desc, six.string_types) and\
|
|
not isinstance(desc, yaml_loader.YamlNull):
|
|
yield error.report.E030('Value is not valid string "{0}"'
|
|
.format(desc), desc)
|
|
|
|
def _valid_format(self, value):
|
|
format_ = str(value).split('/', 1)
|
|
if len(format_) > 1:
|
|
if format_[0] != 'MuranoPL':
|
|
yield error.report.W030(_('Not supported format "{}"'
|
|
'').format(value), value)
|
|
return
|
|
ver = format_[-1]
|
|
if str(ver) not in ['1.0', '1.1', '1.2', '1.3', '1.4']:
|
|
yield error.report.W030(_('Not supported format version "{}"'
|
|
'').format(value), value)
|
|
|
|
def _valid_fullname(self, fullname):
|
|
if not self._check_fqn_name(fullname):
|
|
yield error.report.E073(_('Invalid FullName "{}"')
|
|
.format(fullname), fullname)
|
|
|
|
def _valid_tags(self, value):
|
|
if not isinstance(value, list):
|
|
yield error.report.E070(_('Tags should be a list'), value)
|
|
|
|
def _valid_require(self, value):
|
|
if not isinstance(value, dict):
|
|
yield error.report.E005(_('Require is not a dict type'), value)
|
|
return
|
|
for fqn, ver in six.iteritems(value):
|
|
if not self._check_fqn_name(fqn):
|
|
yield error.report.E005(_('Require key is not valid FQN "{}"'
|
|
'').format(fqn), fqn)
|
|
|
|
def _valid_type(self, value):
|
|
if value not in ('Application', 'Library'):
|
|
yield error.report.E071(_('Type is invalid "{}"').format(value),
|
|
value)
|
|
|
|
def _valid_version(self, version):
|
|
try:
|
|
semantic_version.Version.coerce(str(version))
|
|
except ValueError:
|
|
yield error.report.E071(_('Version format should be compatible '
|
|
'with SemVer not "{}"'
|
|
'').format(version), version)
|
|
|
|
def _valid_logo_ui_existance(self, ast):
|
|
if 'Logo' not in ast:
|
|
yield self._valid_logo('logo.png')
|
|
if 'UI' not in ast:
|
|
yield self._valid_ui('ui.yaml')
|
|
|
|
def _valid_ui(self, value):
|
|
if isinstance(value, six.string_types):
|
|
pkg_type = self._loaded_pkg.read(
|
|
consts.MANIFEST_PATH).yaml()[0]['Type']
|
|
if pkg_type == 'Library':
|
|
return
|
|
if not self._loaded_pkg.exists(os.path.join('UI', value)):
|
|
yield error.report.W073(_('There is no UI file "{}"'
|
|
'').format(value), value)
|
|
else:
|
|
yield error.report.E072(_('UI is not a string'), value)
|
|
|
|
def _valid_logo(self, value):
|
|
if isinstance(value, six.string_types):
|
|
pkg_type = self._loaded_pkg.read(
|
|
consts.MANIFEST_PATH).yaml()[0]['Type']
|
|
if pkg_type == 'Library':
|
|
return
|
|
if not self._loaded_pkg.exists(value):
|
|
yield error.report.W074(_('There is no Logo file "{}"'
|
|
'').format(value), value)
|
|
else:
|
|
yield error.report.E074(_('Logo is not a string'), value)
|
|
|
|
def _valid_classes(self, value):
|
|
if not isinstance(value, dict):
|
|
yield error.report.E074(_('Classes section should be a dict'),
|
|
value)
|
|
return
|
|
|
|
files = set(value.values())
|
|
existing_files = set(self._loaded_pkg.search_for('.*',
|
|
'Classes'))
|
|
for fname in files - existing_files:
|
|
yield error.report.E050(_('File "{}" is present in Manifest, '
|
|
'but not in filesystem'
|
|
'').format(fname), fname)
|
|
for fname in existing_files - files:
|
|
yield error.report.W020(_('File "{}" is not present in Manifest, '
|
|
'but it is in filesystem'
|
|
'').format(fname), fname)
|