Exemplo n.º 1
0
def make_quota_contract(gcp_agent, project_quota, regions):
    """Create a json_contract.Contract that checks GCP quota.

  Args:
    gcp_agent: [GcpAgent] Observation agent on the desired project.
    project_quota: [dict] Minimum desired values keyed by quota metric for
       the observed project.
    regions: [array of (name, dict) tuple]: A list of regions and their
       individual quotas to check.

  Returns:
    json_contract.Contract that will test the project quota.
  """
    quotas_field = 'quotas' + DONT_ENUMERATE_TERMINAL
    builder = GcpContractBuilder(gcp_agent)
    (builder.new_clause_builder('Has Project Quota').inspect_resource(
        'projects',
        resource_id=gcp_agent.default_variables['project']).add_constraint(
            PathPredicate(quotas_field, QuotaPredicate(project_quota))))
    for region, quota in regions:
        (builder.new_clause_builder(
            'Has Regional Quota for {0}'.format(region)).inspect_resource(
                'regions', region).add_constraint(
                    PathPredicate(quotas_field, QuotaPredicate(quota))))

    return builder.build()
Exemplo n.º 2
0
    def test_collect_from_nested_list_found(self):
        # """Ambiguous path through nested lists."""
        context = ExecutionContext()
        source = {'outer': [_LETTER_DICT, _NUMBER_DICT]}
        pred = PathPredicate(PATH_SEP.join(['outer', 'a']))
        values = pred(context, source)
        self.assertEqual([
            PathValue(PATH_SEP.join(['outer[0]', 'a']), 'A'),
            PathValue(PATH_SEP.join(['outer[1]', 'a']), 1)
        ], values.path_values)

        pred = PathPredicate(PATH_SEP.join(['outer', 'z']))
        values = pred(context, source)
        self.assertEqual([PathValue(PATH_SEP.join(['outer[0]', 'z']), 'Z')],
                         values.path_values)
        self.assertEqual([
            MissingPathError(_NUMBER_DICT,
                             'z',
                             path_value=PathValue('outer[1]', _NUMBER_DICT))
        ], values.path_failures)

        pred = PathPredicate(PATH_SEP.join(['outer', 'three']))
        values = pred(context, source)
        self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'three']), 3)],
                         values.path_values)
        self.assertEqual([
            MissingPathError(_LETTER_DICT,
                             'three',
                             path_value=PathValue('outer[0]', _LETTER_DICT))
        ], values.path_failures)
Exemplo n.º 3
0
    def test_collect_from_list_identity(self):
        context = ExecutionContext()
        letters = ['A', 'B', 'C']
        pred = PathPredicate('')
        values = pred(context, letters)
        self.assertEqual([
            PathValue('[0]', 'A'),
            PathValue('[1]', 'B'),
            PathValue('[2]', 'C')
        ], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate(DONT_ENUMERATE_TERMINAL)
        values = pred(context, letters)
        self.assertEqual([PathValue('', letters)], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate(PATH_SEP)
        values = pred(context, letters)
        self.assertEqual([
            PathValue('[0]', 'A'),
            PathValue('[1]', 'B'),
            PathValue('[2]', 'C')
        ], values.path_values)
        self.assertEqual([], values.path_failures)
Exemplo n.º 4
0
    def test_indirect_path(self):
        context = ExecutionContext(test_path='b')
        source = _LETTER_DICT
        indirect_result = PathPredicate(lambda x: x['test_path'])(context,
                                                                  source)
        self.assertTrue(indirect_result)

        direct_result = PathPredicate('b')(context, source)
        self.assertEqual(direct_result.path_values,
                         indirect_result.path_values)
Exemplo n.º 5
0
 def test_collect_from_list_found(self):
   # """Ambiguous path passes through a list element."""
   source = [_LETTER_DICT]
   pred = PathPredicate('a')
   values = pred(source)
   self.assertEqual([PathValue(PATH_SEP.join(['[0]', 'a']), 'A')],
                    values.path_values)
   pred = PathPredicate('b')
   values = pred(source)
   self.assertEqual([PathValue(PATH_SEP.join(['[0]', 'b']), 'B')],
                    values.path_values)
   self.assertEqual([], values.path_failures)
Exemplo n.º 6
0
  def test_collect_from_nested_dict_found(self):
    # """Nested dictionary attribute lookup."""
    source = {'outer': {'inner': _LETTER_DICT}}
    pred = PathPredicate(PATH_SEP.join(['outer', 'inner', 'a']))
    values = pred(source)
    self.assertEqual([PathValue(pred.path, 'A')], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate(PATH_SEP.join(['outer', 'inner', 'b']))
    values = pred(source)
    self.assertEqual([PathValue(pred.path, 'B')], values.path_values)
    self.assertEqual([], values.path_failures)
Exemplo n.º 7
0
  def test_collect_from_dict_found(self):
    # """Normal dictionary attribute lookup."""
    source = _LETTER_DICT
    pred = PathPredicate('a')
    values = pred(source)
    self.assertEqual([PathValue('a', 'A')], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate('b')
    values = pred(source)
    self.assertEqual([PathValue('b', 'B')], values.path_values)
    self.assertEqual([], values.path_failures)
Exemplo n.º 8
0
  def test_collect_plain_terminal_list(self):
    # """Path to a value that is a list."""
    source = {'a': [_LETTER_DICT]}
    pred = PathPredicate('a' + DONT_ENUMERATE_TERMINAL)
    values = pred(source)
    self.assertEqual([PathValue('a', [_LETTER_DICT])], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate(PATH_SEP.join(['a', 'a']))
    values = pred(source)
    self.assertEqual([PathValue(PATH_SEP.join(['a[0]', 'a']), 'A')],
                     values.path_values)
    self.assertEqual([], values.path_failures)
Exemplo n.º 9
0
  def test_collect_filter_good(self):
    source = {'outer': [_LETTER_DICT, _NUMBER_DICT]}
    filter_pred = TestEqualsPredicate(2)
    pred = PathPredicate(PATH_SEP.join(['outer', 'b']), pred=filter_pred)

    # This is a precise test against the exact result returned.
    builder = PathPredicateResultBuilder(source, pred)
    path_0 = PATH_SEP.join(['outer[0]', 'b'])
    path_1 = PATH_SEP.join(['outer[1]', 'b'])

    bad_result = PathValueResult(source=source, target_path=pred.path,
                                 path_value=PathValue(path_0, 'B'),
                                 valid=False, pred=filter_pred)
    good_result = PathValueResult(source=source, target_path=pred.path,
                                  path_value=PathValue(path_1, 2),
                                  valid=True, pred=filter_pred)
    builder.add_result_candidate(PathValue(path_0, 'B'), bad_result)
    builder.add_result_candidate(PathValue(path_1, 2), good_result)
    expect = builder.build(True)

    pred_result = pred(source)
    self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'b']), 2)],
                     pred_result.path_values)

    self.assertEqual(expect, pred_result)
    self.assertEqual(
        [jp.PathPredicateResultCandidate(PathValue(path_0, 'B'), bad_result)],
        pred_result.invalid_candidates)
    self.assertEqual(
        [jp.PathPredicateResultCandidate(PathValue(path_1, 2), good_result)],
        pred_result.valid_candidates)
    self.assertEqual([], pred_result.path_failures)
 def excludes_path_pred(self, path, pred, max=0, **kwargs):
   enumerate_terminals = kwargs.pop('enumerate_terminals', True)
   self.add_constraint(
       CardinalityPredicate(
           PathPredicate(
               path, pred, enumerate_terminals=enumerate_terminals),
           min=0, max=max))
   return self
 def contains_path_pred(self, path, pred, min=1, max=None, **kwargs):
   enumerate_terminals = kwargs.pop('enumerate_terminals', True)
   self.add_constraint(
       CardinalityPredicate(
           PathPredicate(
               path, pred, enumerate_terminals=enumerate_terminals),
           min=min, max=max))
   return self
Exemplo n.º 12
0
  def test_collect_from_list_with_index(self):
    # """Path with explicit list indexes to traverse."""
    source = [_LETTER_DICT, _NUMBER_DICT]
    pred = PathPredicate('[0]')
    values = pred(source)
    self.assertEqual([PathValue('[0]', _LETTER_DICT)], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate('[1]')
    values = pred(source)
    self.assertEqual([PathValue('[1]', _NUMBER_DICT)], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate(PATH_SEP.join(['[1]', 'a']))
    values = pred(source)
    self.assertEqual([PathValue('[1]/a', 1)], values.path_values)
    self.assertEqual([], values.path_failures)
Exemplo n.º 13
0
 def test_collect_from_dict_not_found(self):
   # """Normal dictionary attribute lookup with missing attribute."""
   source = _LETTER_DICT
   pred = PathPredicate('Z')
   values = pred(source)
   self.assertEqual([], values.path_values)
   self.assertEqual([MissingPathError(_LETTER_DICT, 'Z',
                                      path_value=('', _LETTER_DICT))],
                    values.path_failures)
Exemplo n.º 14
0
 def test_path_predicate_result_builder(self):
   source = {}
   for valid in [True, False]:
     for path_pred in [PathPredicate('x'), None]:
       builder = PathPredicateResultBuilder(source, path_pred)
       self.assertEqual(PathPredicateResult(valid, path_pred, source,
                                            valid_candidates=[],
                                            invalid_candidates=[]),
                        builder.build(valid))
Exemplo n.º 15
0
 def test_collect_from_nested_dict_not_found(self):
   # """Nested dictionary attribute lookup with missing element."""
   source = _LETTER_DICT
   pred = PathPredicate(PATH_SEP.join(['a', 'b']))
   values = pred(source)
   self.assertEqual([], values.path_values)
   self.assertEqual(
       [MissingPathError('A', 'b', path_value=PathValue('a', 'A'))],
       values.path_failures)
Exemplo n.º 16
0
  def test_collect_enumerated_terminal_list(self):
    # """Enumerated path to a value that is a list."""
    array = ['A', 'B', 'C']
    source = {'a': array}
    pred = PathPredicate('a' + PATH_SEP)
    values = pred(source)
    self.assertEqual([PathValue('a[0]', 'A'),
                      PathValue('a[1]', 'B'),
                      PathValue('a[2]', 'C')],
                     values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate('a')
    values = pred(source)
    self.assertEqual([PathValue('a[0]', 'A'),
                      PathValue('a[1]', 'B'),
                      PathValue('a[2]', 'C')],
                     values.path_values)
    self.assertEqual([], values.path_failures)
Exemplo n.º 17
0
  def test_collect_from_dict_identity(self):
    source = _LETTER_DICT
    pred = PathPredicate('')
    values = pred(source)

    builder = PathPredicateResultBuilder(source, pred)
    builder.add_result_candidate(
        PathValue('', source),
        PathValueResult(source=source, target_path='',
                        path_value=PathValue('', source), valid=True))
    self.assertEqual(builder.build(True), values)

    self.assertEqual([PathValue('', source)], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate('/')
    values = pred(source)
    self.assertEqual([PathValue('', source)], values.path_values)
    self.assertEqual([], values.path_failures)
Exemplo n.º 18
0
 def test_collect_from_list_not_found(self):
   # """Ambiguous path passes through a list element but cannot be resolved."""
   source = [_LETTER_DICT]
   pred = PathPredicate('Z')
   values = pred(source)
   self.assertEqual([], values.path_values)
   self.assertEqual(
       [MissingPathError(
           _LETTER_DICT, 'Z', path_value=PathValue('[0]', _LETTER_DICT))],
       values.path_failures)
Exemplo n.º 19
0
  def test_path_predicate_eq(self):
    pred_a = PathPredicate('x')
    pred_b = PathPredicate('y')
    self.assertNotEqual(pred_a, pred_b)

    pred_a = PathPredicate('x')
    pred_b = PathPredicate('x')
    self.assertEqual(pred_a, pred_b)

    pred_a = PathPredicate('x', pred=PathPredicate('X'))
    self.assertNotEqual(pred_a, pred_b)

    pred_b = PathPredicate('x', pred=PathPredicate('X'))
    self.assertEqual(pred_a, pred_b)
Exemplo n.º 20
0
 def test_collect_from_nested_list_not_found(self):
   # """Path through nested lists that cannot be resolved."""
   source = {'outer': [_LETTER_DICT, _NUMBER_DICT]}
   pred = PathPredicate(PATH_SEP.join(['outer', 'X']))
   values = pred(source)
   self.assertEqual([], values.path_values)
   self.assertEqual(
       [MissingPathError(
           _LETTER_DICT, 'X',
           path_value=PathValue('outer[0]', _LETTER_DICT)),
        MissingPathError(
            _NUMBER_DICT, 'X',
            path_value=PathValue('outer[1]', _NUMBER_DICT))],
       values.path_failures)
Exemplo n.º 21
0
def make_quota_result(context, valid, source, require, metric):
  """Construct the values returned by QuotaPredicate.

  These are what is currently implemented, but the current implementation
  is not correct because it uses PathValue of made up paths rather than
  expressing that we are looking for the difference among two paths.
  """
  diff = FieldDifference('limit', 'usage')
  for value in source:
    if value['metric'] == metric:
      pred = PathPredicate('', pred=NUM_GE(require[metric]), transform=diff)
      return pred(context, value)

  raise ValueError('Missing metric')
Exemplo n.º 22
0
    def test_collect_from_dict_transform(self):
        context = ExecutionContext()
        source = {'a': 7, 'b': 4}
        pred = PathPredicate('',
                             transform=lambda ctxt, val: val['a'] - val['b'])
        expect = 7 - 4
        values = pred(context, source)

        builder = PathPredicateResultBuilder(source, pred)
        builder.add_result_candidate(
            PathValue('', source),
            PathValueResult(source=source,
                            target_path='',
                            path_value=PathValue('', expect),
                            valid=True))
        self.assertEqual(builder.build(True), values)
Exemplo n.º 23
0
    def __call__(self, context, value):
        """Implements ValuePredicate.

    Args:
       context: [ExecutionContext] The execution context to evaluate within.
       values: [array of dict] A list of dictionary resource quota descriptions
          following the format returned described by the "quotas" attribute of
          https://cloud.google.com/compute/docs/reference/latest/projects#resource
    """
        builder = KeyedPredicateResultBuilder(self)
        # NOTE(20180710):
        # b/111302333: get() because 'metric' is not always provided.
        dictified = {elem.get('metric'): elem for elem in value}

        bad_metrics = []
        for metric, expect in self.__minimum_quota.items():
            found = dictified.get(metric)
            if found is None:
                bad_metrics.append(metric)
                builder.add_result(
                    metric,
                    PathValueResult(source=None,
                                    target_path='metric',
                                    path_value=PathValue('', value),
                                    valid=False,
                                    pred=EQUIVALENT(metric),
                                    comment='Missing metric value.'))
                continue
            pred = PathPredicate('',
                                 pred=NUM_GE(expect),
                                 transform=self.__diff)
            result = pred(context, found)
            builder.add_result(metric, result)
            if not result:
                bad_metrics.append(metric)

        if bad_metrics:
            builder.comment = 'Insufficient {0}.'.format(
                ' and '.join(bad_metrics))
            valid = False
        else:
            valid = True
            builder.comment = 'Satisfied all {0} metrics.'.format(
                len(self.__minimum_quota))

        return builder.build(valid)
Exemplo n.º 24
0
    def test_collect_from_list_of_list_with_index(self):
        # """Path with explicit list indexes to traverse through nested lists."""
        context = ExecutionContext()
        upper = ['A', 'B', 'C']
        lower = ['a', 'b', 'c']
        letters = [upper, lower]
        arabic = [1, 2, 3]
        roman = ['i', 'ii', 'iii']
        numbers = [arabic, roman]
        source = [letters, numbers]

        # By default, values that are lists get expanded (one level)
        pred = PathPredicate('[1]')
        values = pred(context, source)
        self.assertEquals(
            [PathValue('[1][0]', arabic),
             PathValue('[1][1]', roman)], values.path_values)
        self.assertEqual([], values.path_failures)

        # If we dont want to expand, then decorate with DONT_ENUMERATE_TERMINAL.
        pred = PathPredicate('[0]' + DONT_ENUMERATE_TERMINAL)
        values = pred(context, source)
        self.assertEqual([PathValue('[0]', letters)], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate('[1]' + DONT_ENUMERATE_TERMINAL)
        values = pred(context, source)
        self.assertEqual([PathValue('[1]', numbers)], values.path_values)
        self.assertEqual([], values.path_failures)

        # Go out one more level
        pred = PathPredicate('[1][0]' + DONT_ENUMERATE_TERMINAL)
        values = pred(context, source)
        self.assertEqual([PathValue('[1][0]', arabic)], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate('[1][0]')
        values = pred(context, source)
        self.assertEqual([
            PathValue('[1][0][0]', 1),
            PathValue('[1][0][1]', 2),
            PathValue('[1][0][2]', 3)
        ], values.path_values)
        self.assertEqual([], values.path_failures)

        # Go all the way down.
        pred = PathPredicate('[1][0][2]')
        values = pred(context, source)
        self.assertEqual([PathValue('[1][0][2]', 3)], values.path_values)
        self.assertEqual([], values.path_failures)
  def excludes_match(self, match_spec, max=0, **kwargs):
    match_kwargs = kwargs.pop('match_kwargs', {})
    if isinstance(match_spec, list):
      enumerate_terminals = kwargs.pop('enumerate_terminals', False)
      constraint = LIST_MATCHES(match_spec, **match_kwargs)
      self.add_constraint(
          CardinalityPredicate(
              PathPredicate(
                  '', constraint, enumerate_terminals=enumerate_terminals),
              min=0, max=max))
    elif isinstance(match_spec, dict):
      self.add_constraint(
          CardinalityPredicate(
              DICT_MATCHES(match_spec, **match_kwargs),
              min=0, max=max))
    else:
      raise ValueError('match_spec must be a dict or list, not a {0}'
                       .format(match_spec.__class__.__name__))

    return self
Exemplo n.º 26
0
    def test_path_conjunction(self):
        context = ExecutionContext()
        text = 'x=X, a=A, b=B, z=Z'
        aA = jp.STR_SUBSTR('a=A')
        bB = jp.STR_SUBSTR('b=B')
        conjunction = jp.AND([aA, bB])
        pred = PathPredicate('value', conjunction)
        source = {'value': text, 'wrong': 'a=A', 'another': 'b=B'}

        conjunction_result = conjunction(context, text)
        builder = PathPredicateResultBuilder(source, pred)
        builder.add_result_candidate(
            PathValue('value', text),
            conjunction_result.clone_with_source(source=source,
                                                 base_target_path='value',
                                                 base_value_path='value'))
        expect = builder.build(True)

        pred_result = pred(context, source)
        self.assertEqual(expect, pred_result)
Exemplo n.º 27
0
  def test_path_predicate_result_eq(self):
    source = {}
    path_pred = PathPredicate('x')
    a_result = path_pred(source)  # dont care, just something well formed.

    result_a = PathPredicateResult(
        True, path_pred, source,
        valid_candidates=[], invalid_candidates=[])
    result_b = PathPredicateResult(
        True, path_pred, source,
        valid_candidates=[], invalid_candidates=[])
    self.assertEqual(result_a, result_b)

    # Only valid different.
    result_b = PathPredicateResult(
        False, path_pred, source,
        valid_candidates=[], invalid_candidates=[])
    self.assertNotEqual(result_a, result_b)

    # Only filter different.
    result_b = PathPredicateResult(
        True, PathPredicate('y'), source,
        valid_candidates=[], invalid_candidates=[])
    self.assertNotEqual(result_a, result_b)

    # Only source different.
    result_b = PathPredicateResult(
        True, path_pred, [source],
        valid_candidates=[], invalid_candidates=[])
    self.assertNotEqual(result_a, result_b)

    # Only valid candidates different.
    result_b = PathPredicateResult(
        True, path_pred, source,
        valid_candidates=[
            PathPredicateResultCandidate(PathValue('x', 0), a_result)],
        invalid_candidates=[])
    self.assertNotEqual(result_a, result_b)

    # Only invalid candidates different.
    result_b = PathPredicateResult(
        True, path_pred, source,
        valid_candidates=[],
        invalid_candidates=[
            PathPredicateResultCandidate(PathValue('x', 0), a_result)])
    self.assertNotEqual(result_a, result_b)

    # More fully defined equal.
    result_a = PathPredicateResult(
        True, path_pred, source,
        valid_candidates=[
            PathPredicateResultCandidate(PathValue('x', 0), a_result)],
        invalid_candidates=[
            PathPredicateResultCandidate(PathValue('x', 0), a_result)])
    result_b = PathPredicateResult(
        True, path_pred, source,
        valid_candidates=[
            PathPredicateResultCandidate(PathValue('x', 0), a_result)],
        invalid_candidates=[
            PathPredicateResultCandidate(PathValue('x', 0), a_result)])
    self.assertEqual(result_a, result_b)