def validator_test(self, cfg, messages):
     ctx = validation.Context()
     bot_groups_config.validate_settings(cfg, ctx)
     self.assertEquals(ctx.result().messages, [
         validation.Message(severity=logging.ERROR, text=m)
         for m in messages
     ])
Beispiel #2
0
 def validator_test(self, validator, cfg, messages):
   ctx = validation.Context()
   validator(cfg, ctx)
   self.assertEquals(ctx.result().messages, [
     validation.Message(severity=logging.ERROR, text=m)
     for m in messages
   ])
Beispiel #3
0
 def validator_test(self, bm, messages):
     ctx = validation.Context()
     actual = pools_config._resolve_bot_monitoring(ctx, bm)
     self.assertEqual(ctx.result().messages, [
         validation.Message(severity=logging.ERROR, text=m)
         for m in messages
     ])
     return actual
 def validator_test(self, cfg, messages):
     ctx = validation.Context()
     self.assertIsInstance(cfg, config_pb2.SettingsCfg)
     config._validate_settings(cfg, ctx)
     self.assertEquals(ctx.result().messages, [
         validation.Message(severity=logging.ERROR, text=m)
         for m in messages
     ])
 def test_validate_security_config_bad_regexp(self):
     ctx = validation.Context()
     config.validate_security_config(
         security_config_pb2.SecurityConfig(internal_service_regexp=['???'
                                                                     ], ),
         ctx)
     self.assertEqual(ctx.result().messages, [
         validation.Message(
             "internal_service_regexp: bad regexp '???' - nothing to repeat",
             40),
     ])
Beispiel #6
0
def validate_buildbucket_cfg(cfg, ctx):
    import swarmingcfg

    acl_set_names = set()
    for i, acl_set in enumerate(cfg.acl_sets):
        with ctx.prefix('ACL set #%d (%s): ', i + 1, acl_set.name):
            if not acl_set.name:
                ctx.error('name is unspecified')
            elif not ACL_SET_NAME_RE.match(acl_set.name):
                ctx.error('invalid name "%s" does not match regex %r',
                          acl_set.name, ACL_SET_NAME_RE.pattern)
            elif acl_set.name in acl_set_names:
                ctx.error('duplicate name "%s"', acl_set.name)
            acl_set_names.add(acl_set.name)

            validate_access_list(acl_set.acls, ctx)

    mixin_ctx = validation.Context(  # pragma: no cover
        on_message=lambda msg: ctx.msg(msg.severity, '%s', msg.text))
    swarmingcfg.validate_builder_mixins(cfg.builder_mixins, mixin_ctx)
    mixins_are_valid = not mixin_ctx.result().has_errors
    mixin_by_name = {m.name: m for m in cfg.builder_mixins}

    bucket_names = set()

    for i, bucket in enumerate(cfg.buckets):
        with ctx.prefix('Bucket %s: ', bucket.name or ('#%d' % (i + 1))):
            try:
                errors.validate_bucket_name(bucket.name,
                                            project_id=ctx.project_id)
            except errors.InvalidInputError as ex:
                ctx.error('invalid name: %s', ex.message)
            else:
                if bucket.name in bucket_names:
                    ctx.error('duplicate bucket name')
                else:
                    bucket_names.add(bucket.name)
                    if i > 0 and bucket.name < cfg.buckets[i - 1].name:
                        ctx.warning('out of order')

            validate_access_list(bucket.acls, ctx)
            for name in bucket.acl_sets:
                if name not in acl_set_names:
                    ctx.error(
                        'undefined ACL set "%s". '
                        'It must be defined in the same file', name)

            if bucket.HasField('swarming'):  # pragma: no cover
                with ctx.prefix('swarming: '):
                    swarmingcfg.validate_project_cfg(bucket.swarming,
                                                     mixin_by_name,
                                                     mixins_are_valid, ctx)
Beispiel #7
0
    def validate_config(self, request):
        logging.debug("requester: %s, config_set: %s, paths: %s",
                      auth.get_current_identity().to_bytes(),
                      request.config_set, [f.path for f in request.files])
        if not request.config_set:
            raise endpoints.BadRequestException('Must specify a config_set')
        if not request.files:
            raise endpoints.BadRequestException(
                'Must specify files to validate')
        for f in request.files:
            if not f.path:
                raise endpoints.BadRequestException(
                    'Must specify the path of a file')
        if not acl.has_validation_access():
            logging.warning('%s does not have validation access',
                            auth.get_current_identity().to_bytes())
            raise endpoints.ForbiddenException()
        if not can_read_config_set(request.config_set):
            logging.warning('%s does not have access to %s',
                            auth.get_current_identity().to_bytes(),
                            request.config_set)
            raise endpoints.ForbiddenException()

        futs = []
        for f in request.files:
            ctx = cfg_validation.Context()
            with ctx.prefix(f.path + ': '):
                futs.append(
                    validation.validate_config_async(request.config_set,
                                                     f.path,
                                                     f.content,
                                                     ctx=ctx))

        ndb.Future.wait_all(futs)
        # return the severities and the texts
        msgs = []
        for f, fut in zip(request.files, futs):
            for msg in fut.get_result().messages:
                msgs.append(
                    cfg_endpoint.ValidationMessage(
                        path=f.path,
                        severity=common.Severity.lookup_by_number(
                            msg.severity),
                        text=msg.text))

        return self.ValidateConfigResponseMessage(messages=msgs)
Beispiel #8
0
    def test_context_metadata(self):
        ctx = validation.Context()

        ctx.config_set = 'services/foo'
        self.assertEqual(ctx.service_id, 'foo')
        self.assertEqual(ctx.project_id, None)
        self.assertEqual(ctx.ref, None)

        ctx.config_set = 'projects/foo'
        self.assertEqual(ctx.service_id, None)
        self.assertEqual(ctx.project_id, 'foo')
        self.assertEqual(ctx.ref, None)

        ctx.config_set = 'projects/foo/refs/a'
        self.assertEqual(ctx.service_id, None)
        self.assertEqual(ctx.project_id, 'foo')
        self.assertEqual(ctx.ref, 'refs/a')
Beispiel #9
0
def validate_config_async(config_set, path, content, ctx=None):
  """Validates a config against built-in and external validators.

  External validators are defined in validation.cfg,
  see proto/service_config.proto.

  Returns:
    components.config.validation_context.Result.
  """
  ctx = ctx or validation.Context()

  # Check the config against built-in validators,
  # defined using validation.self_rule.
  validation.validate(config_set, path, content, ctx=ctx)

  all_services = yield services.get_services_async()
  futures = []
  for service in all_services:
    futures.append(
        _validate_by_service_async(service, config_set, path, content, ctx))
  yield futures
  raise ndb.Return(ctx.result())
 def is_valid(**fields):
     ctx = validation.Context()
     config.validate_settings_cfg(config_pb2.SettingsCfg(**fields), ctx)
     return not ctx.messages
Beispiel #11
0
    def test_notify_gitiles_rejection(self):
        ctx = validation.Context()
        ctx.error('err')
        ctx.warning('warn')

        base = gitiles.Location.parse('https://example.com/x/+/infra/config')
        new_rev = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
        new_loc = base._replace(treeish=new_rev)
        old_rev = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
        old_loc = base._replace(treeish=old_rev)

        self.mock(notifications, '_send', mock.Mock())

        john = gitiles.Contribution('John', '*****@*****.**',
                                    datetime.datetime(2015, 1, 1))
        commit = gitiles.Commit(sha=new_rev,
                                tree='badcoffee',
                                parents=[],
                                author=john,
                                committer=john,
                                message='New config',
                                tree_diff=None)
        self.mock(gitiles, 'get_log_async',
                  mock.Mock(return_value=ndb.Future()))
        gitiles.get_log_async.return_value.set_result(
            gitiles.Log(commits=[commit], next_cursor=None))

        self.mock(template, 'render', mock.Mock())

        self.mock(auth, 'list_group', mock.Mock())
        auth.list_group.return_value = auth.GroupListing([
            auth.Identity('user', '*****@*****.**'),
            auth.Identity('service', 'foo'),
        ], [], [])

        # Notify.

        notifications.notify_gitiles_rejection('projects/x', new_loc,
                                               ctx.result())

        self.assertTrue(notifications._send.called)
        email = notifications._send.call_args[0][0]
        self.assertEqual(
            email.sender,
            'sample-app.appspot.com <*****@*****.**>')
        self.assertEqual(email.subject, 'Config revision aaaaaaa is rejected')
        self.assertEqual(email.to, ['John <*****@*****.**>'])
        self.assertEqual(email.cc, {'*****@*****.**'})

        template.render.assert_called_with(
            'templates/validation_notification.html', {
                'author':
                'John',
                'messages': [{
                    'severity': 'ERROR',
                    'text': 'err'
                }, {
                    'severity': 'WARNING',
                    'text': 'warn'
                }],
                'rev_link':
                new_loc,
                'rev_hash':
                'aaaaaaa',
                'rev_repo':
                'x',
                'cur_rev_hash':
                None,
                'cur_rev_link':
                None,
            })

        # Do not send second time.
        notifications._send.reset_mock()
        notifications.notify_gitiles_rejection('projects/x', new_loc,
                                               ctx.result())
        self.assertFalse(notifications._send.called)

        # Now with config set.

        ndb.Key(notifications.Notification, str(new_loc)).delete()

        storage.ConfigSet(id='projects/x',
                          latest_revision=old_rev,
                          latest_revision_url=str(old_loc),
                          location=str(base)).put()

        template.render.reset_mock()
        notifications.notify_gitiles_rejection('projects/x', new_loc,
                                               ctx.result())
        template.render.assert_called_with(
            'templates/validation_notification.html', {
                'author':
                'John',
                'messages': [{
                    'severity': 'ERROR',
                    'text': 'err'
                }, {
                    'severity': 'WARNING',
                    'text': 'warn'
                }],
                'rev_link':
                new_loc,
                'rev_hash':
                'aaaaaaa',
                'rev_repo':
                'x',
                'cur_rev_hash':
                'bbbbbbb',
                'cur_rev_link':
                old_loc,
            })
Beispiel #12
0
 def setUp(self):
     super(TaskTemplateBaseTest, self).setUp()
     self._canary_dice_roll = 5000  # 50%
     self._randint_normal = random.randint
     random.randint = lambda *_: self._canary_dice_roll
     self.ctx = validation.Context()
Beispiel #13
0
 def setUp(self):
     self.ctx = validation.Context()
     self.doc = directory_occlusion.Checker()
 def test_validate_security_config_ok(self):
     ctx = validation.Context()
     config.validate_security_config(security_config_pb2.SecurityConfig(),
                                     ctx)
     self.assertEqual(ctx.result().messages, [])
 def call(self, fields, allow_internal=False):
     ctx = cfgvalidation.Context()
     val = validation.Validator(ctx, test_db(), allow_internal)
     val.validate(realms_config_pb2.RealmsCfg(**fields))
     return ctx
Beispiel #16
0
 def setUp(self):
     self.ctx = validation.Context()
Beispiel #17
0
 def make_subctx():
   return validation.Context(
       on_message=lambda msg: ctx.msg(msg.severity, '%s', msg.text))