Esempio n. 1
0
    def _valid_methods(self, value):
        if not isinstance(value, dict):
            if not isinstance(value, yaml_loader.YamlNull):
                yield error.report.E046(_('Methods are not a dict'), value)
            return
        for method_name, method_data in value.items():
            if not isinstance(method_data, dict):
                if method_data:
                    yield error.report.E046(_('Method is not a dict'),
                                            method_name)
                return

            if not (method_name in SPECIAL_METHODS
                    or METHOD_NAME_REGEX.match(method_name)):
                yield error.report.E054(
                    _('Invalid name of method "{}"').format(method_name),
                    method_name)
            scope = method_data.get('Scope')
            if scope:
                yield self._valid_scope(scope)
            usage = method_data.get('Usage')
            if usage:
                yield self._valid_method_usage(usage)
            arguments = method_data.get('Arguments')
            if arguments:
                yield self._valid_arguments(arguments)
            body = method_data.get('Body')
            if body:
                yield self._valid_body(body)
            yield self._valid_keywords(method_data.keys(), METHOD_KEYWORDS)
Esempio n. 2
0
 def _valid_arguments(self, arguments):
     if isinstance(arguments, dict) and len(arguments) > 1:
         yield error.report.E048(
             _('It is not safe to define methods '
               'arguments as a dict with several keys'), arguments)
         return
     elif not isinstance(arguments, (list, dict)):
         yield error.report.E046(
             _('Methods arguments should be a list or '
               'dict'), arguments)
         return
     if isinstance(arguments, dict):
         arguments = [arguments]
     for argument in arguments:
         if not isinstance(argument, dict) or len(argument) != 1:
             yield error.report.E046(
                 _('Methods single argument should be '
                   'a one key dict'), argument)
         else:
             name = next(six.iterkeys(argument))
             if not self._check_name(name):
                 yield error.report.E054(
                     _('Invalid name of argument "{}"').format(name), name)
             val = next(six.itervalues(argument))
             contract = val.get('Contract')
             if contract:
                 yield self._valid_contract(contract)
             usage = val.get('Usage')
             if usage:
                 yield self._valid_argument_usage(usage)
             yield self._valid_keywords(val, METHOD_ARGUMENTS_KEYWORDS)
Esempio n. 3
0
 def _valid_contract(self, contract):
     if isinstance(contract, list):
         if len(contract) > 1:
             if len(contract) < 3:
                 if isinstance(contract[1], int):
                     return
             elif len(contract) < 4:
                 if isinstance(contract[1], int) and \
                         isinstance(contract[2], int):
                     return
             for con in contract:
                 yield self._valid_contract(con)
         elif len(contract) == 1:
             yield self._valid_contract(contract[0])
     elif isinstance(contract, dict):
         if not contract:
             return
         for c_key, c_value in contract.items():
             yield self._valid_string(c_key)
             yield self._valid_contract(c_value)
     elif isinstance(contract, six.string_types):
         if not self.yaql_checker(contract) or \
                 not contract.startswith('$.') and contract != '$':
             yield error.report.W048(
                 _('Contract is not valid yaql "{}"'
                   '').format(contract), contract)
     else:
         yield error.report.W048(
             _('Contract is not valid yaql "{}"'
               '').format(contract), contract)
Esempio n. 4
0
 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 value.items():
         if not self._check_fqn_name(fqn):
             yield error.report.E005(_('Require key is not valid FQN "{}"'
                                       '').format(fqn), fqn)
Esempio n. 5
0
 def _valid_argument_usage(self, usage):
     if self._loaded_pkg.format_version < '1.4':
         yield error.report.E052(
             _('Arguments usage is available '
               'since 1.4'), usage)
     if usage not in frozenset(['Standard', 'VarArgs', 'KwArgs']):
         yield error.report.E053(
             _('Usage is invalid value "{}"').format(usage), usage)
Esempio n. 6
0
 def _valid_scope(self, scope):
     if self._loaded_pkg.format_version >= '1.4':
         if scope is not None and scope not in ('Public', 'Session'):
             yield error.report.E044(
                 _('Wrong Scope "{}"').format(scope), scope)
     else:
         yield error.report.E044(
             _('Scope is not supported version '
               'earlier than 1.3"'), scope)
Esempio n. 7
0
 def _valid_application(self, application):
     if not isinstance(application, dict):
         yield error.report.E084(_('Application is not a dict'),
                                 application)
         return
     for name, value in application.items():
         if not self._check_name(name):
             if name != '?':
                 yield error.report.E083(_('Wrong name in UI file "{}"')
                                         .format(name), name)
Esempio n. 8
0
 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)
Esempio n. 9
0
 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)
Esempio n. 10
0
 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)
Esempio n. 11
0
 def _known_directories(self):
     files = set(self._loaded_pkg.search_for('^[^/]+$'))
     try:
         logo_file = next(self._loaded_pkg.search_for('^manifest.yaml$'))\
             .yaml()[0]['Logo']
     except Exception:
         logo_file = 'logo.png'
     for file_ in files - KNOWN_FILES_DIR - {logo_file}:
         yield error.report.W120(
             _('Unknown "{}" in the package').format(file_), file_)
     for file_ in REQUIRED_FILES_DIR - files:
         yield error.report.W121(
             _('Missing "{}" in the package').format(file_), file_)
Esempio n. 12
0
 def _valid_method_usage(self, usage):
     if usage == 'Action':
         if self._loaded_pkg.format_version >= '1.4':
             yield error.report.W045(
                 _('Usage "{}" is deprecated since 1.4'
                   '').format(usage), usage)
     elif usage in frozenset(['Static', 'Extension']):
         if self._loaded_pkg.format_version <= '1.3':
             yield error.report.W045(
                 _('Usage "{}" is available from 1.3').format(usage), usage)
     elif usage != 'Runtime':
         yield error.report.W045(
             _('Unsupported usage type "{}" ').format(usage), usage)
Esempio n. 13
0
 def _valid_name(self, value):
     if not isinstance(value, six.string_types):
         yield error.report.E011(
             _('Invalid class name "{}". '
               'Class name should be a string').format(value), value)
     elif (value.startswith('__') or not CLASSNAME_REGEX.match(value)):
         yield error.report.E011(
             _('Invalid class name "{}"').format(value), value)
     else:
         # NOTE (kzaitsev): allow short uppercase names like Q, IP, CDN
         if (not value[0].isupper()
                 or (len(value) > 3 and value == value.upper())):
             yield error.report.W011(
                 _('Class name "{}" not in CamelCase').format(value), value)
Esempio n. 14
0
    def _valid_namespaces(self, value):
        if not isinstance(value, dict):
            yield error.report.E044(_('Wrong type of namespace'), value)
            return

        for name, fqn in value.items():
            if not self._check_fqn_name(fqn):
                yield error.report.W060(
                    _('Wrong namespace fqn '
                      '"{}"').format(fqn), fqn)
            if not self._check_name(name) and name != '=':
                yield error.report.E060(
                    _('Wrong name for namespace '
                      '"{}"').format(fqn), fqn)
Esempio n. 15
0
 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)
Esempio n. 16
0
 def _valid_body(self, body):
     if not isinstance(body, (list, six.string_types, dict)):
         yield error.report.E045(
             _('Body is not a list or scalar/yaql '
               'expression'), body)
     else:
         yield self.code_structure.codeblock(body)
Esempio n. 17
0
    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)
Esempio n. 18
0
 def _valid_import(self, import_, can_be_list=True):
     if can_be_list and isinstance(import_, list):
         for imp in import_:
             yield self._valid_import(imp, False)
     elif not self._check_ns_fqn_name(import_):
         yield error.report.E025(
             _('Wrong namespace or FNQ of extended '
               'class "{0}"').format(import_), import_)
Esempio n. 19
0
 def _valid_applies(self, applies, allow_list=True):
     if allow_list and isinstance(applies, list):
         for apl in applies:
             yield self._valid_applies(apl, False)
     else:
         if not isinstance(applies, six.string_types) or \
                 applies not in APPLIES_VALUES:
             yield error.report.E028(
                 _('Wrong Applies "{0}"').format(applies), applies)
Esempio n. 20
0
    def _to_list(self, error_chain, select=None, ignore=None):
        errors = []
        while True:
            try:
                e = next(error_chain)
            except StopIteration:
                break
            except Exception:
                exc_info = sys.exc_info()
                tb = exc_info[2]
                while tb.tb_next:
                    tb = tb.tb_next
                validator_class = tb.tb_frame.f_locals.get('self')
                check_name = tb.tb_frame.f_code.co_name
                check_locals = tb.tb_frame.f_locals.copy()
                check_locals.pop('self', None)
                if validator_class:
                    msg = (_('Checker {} from {} failed!'
                             '').format(check_name,
                                        validator_class.__class__.__name__))
                else:
                    msg = (_('Checker {} failed!'
                             '').format(check_name))
                LOG.error('{} {}\n{}'.format(msg,
                                             _('Checker locals:'),
                                             pprint.pformat(check_locals)),
                          exc_info=exc_info)
                e = error.report.E000(
                    msg + _(' See more information in logs.'))
            if isinstance(e, types.GeneratorType):
                errors.extend(self._to_list(e, select, ignore))
            else:
                if ((select and e.code not in select) or
                        (ignore and e.code in ignore)):
                    LOG.debug('Skipped: {code} {message}'
                              ''.format(**e.to_dict()))
                    continue
                LOG.debug('Reported: {code} {message}'
                          ''.format(**e.to_dict()))
                errors.append(e)

        return sorted(errors, key=lambda err: err.code)
Esempio n. 21
0
    def _run_single(self, file_):
        reports_chain = []

        def run_helper(name, checkers, data):
            for checker in checkers:
                result = checker(data)
                if result:
                    reports_chain.append(result)

        try:
            multi_documents = file_.yaml()
        except Exception as e:
            reports_chain.append([
                error.report.E002('Yaml Error: {0}'.format(e), e)])
        else:
            if multi_documents is None:
                multi_documents = [{}]

            if len(multi_documents) > 1 and not self._allows_multi:
                reports_chain.append([
                    error.report.E005(_('Multi document is not allowed in {}')
                                      .format(file_._path))])

            for ast in multi_documents:
                file_check = self._checkers.get(None)
                if file_check:
                    run_helper(None, file_check['checkers'], ast)
                for key, value in ast.items():
                    checkers = self._checkers.get(key)
                    if checkers:
                        run_helper(key, checkers['checkers'], ast[key])
                    else:
                        reports_chain.append(self._unknown_keyword(key, value))
                missing = set(key for key, value in
                              self._checkers.items()
                              if value['required']) - set(ast.keys())
                for m in missing:
                    reports_chain.append([
                        error.report.E020(_('Missing required key "{}"')
                                          .format(m), m)])

        return itertools.chain(*reports_chain)
Esempio n. 22
0
def load_package(path, quiet=False):
    for loader_cls in PACKAGE_LOADERS:
        loader = loader_cls.try_load(path)
        if loader is not None:
            return loader
        else:
            if not quiet:
                LOG.debug("{} failed to load '{}'"
                          "".format(loader_cls.__name__, path))
    else:
        raise ValueError(_('Can not load package: "{}"').format(path))
Esempio n. 23
0
 def _valid_extends(self, value, can_be_list=True):
     if can_be_list and isinstance(value, list):
         for cls in value:
             yield self._valid_extends(cls, False)
     elif isinstance(value, six.string_types):
         if not self._check_ns_fqn_name(value):
             yield error.report.E025(
                 _('Wrong FNQ of extended class "{}"'
                   '').format(value), value)
     else:
         yield error.report.E025("Wrong type of Extends field", value)
Esempio n. 24
0
 def _valid_form(self, form):
     for named_params in form:
         for key, value in named_params.items():
             if key in STR_FIELDS:
                 if not isinstance(value, six.string_types):
                     yield error.report.E040(_('Value of {} should be '
                                               'string not "{}"')
                                             .format(key, value), key)
             elif key in BOOL_FIELDS:
                 if not isinstance(value, bool):
                     yield error.report.E081(_('Value of {} should be '
                                               'boolean not "{}"')
                                             .format(key, value), key)
             elif key in INT_FIELDS:
                 if not isinstance(value, int):
                     yield error.report.E082(_('Value of {} should be '
                                               'int not "{}"')
                                             .format(key, value), key)
             elif key == 'type':
                 yield self._valid_field_type(value)
Esempio n. 25
0
 def _valid_properties(self, properties):
     if not isinstance(properties, dict):
         yield error.report.E026(_('Properties should be a dict'),
                                 properties)
         return
     for property_name, property_data in properties.items():
         usage = property_data.get('Usage')
         if usage:
             if usage not in PROPERTIES_USAGE_VALUES:
                 yield error.report.E042(
                     _('Not allowed usage "{}"'
                       '').format(usage), usage)
         contract = property_data.get('Contract')
         if contract is not None:
             yield self._valid_contract(contract)
         else:
             yield error.report.E047(
                 _('Missing Contract in property "{}"').format(
                     property_name), property_name)
         yield self._valid_keywords(property_data.keys(),
                                    PROPERTIES_KEYWORDS)
Esempio n. 26
0
 def _valid_version(self, version):
     if str(version) not in UI_VERSION:
         yield error.report.W082(_('Incorrect version of UI file "{}"')
                                 .format(version), version)
Esempio n. 27
0
 def _unknown_keyword(self, key, value):
     yield error.report.W010(_('Unknown keyword "{}"').format(key), key)
Esempio n. 28
0
 def _valid_string(self, value):
     if not isinstance(value, six.string_types):
         yield error.report.E040(_('Value is not a string "{}"'
                                   '').format(value), value)
Esempio n. 29
0
 def _valid_inherited(self, inherited):
     if not isinstance(inherited, bool):
         yield error.report.E027(
             _('Inherited is not bool "{0}"').format(inherited), inherited)
Esempio n. 30
0
 def _valid_cardinality(self, cardinality):
     if cardinality not in ('One', 'Many'):
         yield error.report.E027(
             _('Wrong Cardinality "{0}"').format(cardinality), cardinality)