def test_missing_required_key(self, test_name, key):
     """A rule missing a required key returns error."""
     test_rule = generate_ingress_rule()
     test_rule.pop(key)
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_allowed_missing_ip_protocol(self):
     """Rule missing IPProtocol in an allow predicate returns error."""
     test_rule = generate_ingress_rule()
     test_rule['allowed'][0].pop('IPProtocol')
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_direction_egress_source_ranges(self):
     """Rule with direction set to EGRESS + sourceRanges returns error."""
     test_rule = generate_egress_rule()
     test_rule['sourceRanges'] = ['10.8.0.0/24']
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_invalid_direction(self):
     """Rule with direction set to invalid returns error."""
     test_rule = generate_ingress_rule()
     test_rule['direction'] = 'INVALID'
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_no_allowed_or_denied(self):
     """A rule with no allow or deny ports returns error."""
     test_rule = generate_ingress_rule()
     test_rule.pop('allowed')
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_denied_rule(self):
     """A rule with denied ports returns None."""
     test_rule = generate_ingress_rule()
     allowed = test_rule.pop('allowed')
     test_rule['denied'] = allowed
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsNone(err, 'expected no error message, got err: %s' % err)
 def test_allowed_and_denied(self):
     """A rule with allow and deny ports returns error."""
     test_rule = generate_ingress_rule()
     test_rule['denied'] = [{'IPProtocol': u'udp'}]
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_unknown_key(self):
     """A rule with an unknown key returns error."""
     test_rule = generate_ingress_rule()
     test_rule['someUnknownKey'] = True
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
 def test_missing_allowed_or_deny(self):
     """A rule missing either allowed returns error."""
     test_rule = generate_ingress_rule()
     test_rule.pop('allowed')
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
Ejemplo n.º 10
0
 def test_ingress_keys_with_more_than_256_values(self, test_name, key):
     """Ingress rule entries with more than 256 values return error."""
     test_rule = generate_ingress_rule()
     test_rule['direction'] = 'INGRESS'
     test_rule[key] = range(257)
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
Ejemplo n.º 11
0
 def test_source_and_destination_ranges(self):
     """Rule with sourceRanges and destinationRanges returns error."""
     test_rule = generate_ingress_rule()
     test_rule['sourceRanges'] = [u'10.8.0.0/24']
     test_rule['destinationRanges'] = [u'10.8.0.0/24']
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
Ejemplo n.º 12
0
 def test_tag_name_validation(self, test_name, tag, expected):
     """A rule with invalid tag raises InvalidFirewallRuleError."""
     test_rule = generate_ingress_rule()
     test_rule['sourceTags'] = [tag]
     err = rule_validator.validate_gcp_rule(test_rule)
     res = err is None
     self.assertEqual(
         expected, res,
         'expected %s got %s with err: %s' % (expected, res, err))
Ejemplo n.º 13
0
 def test_name_validation(self, test_name, name, expected):
     """Test different name validations."""
     test_rule = generate_ingress_rule()
     test_rule['name'] = name
     err = rule_validator.validate_gcp_rule(test_rule)
     res = err is None
     self.assertEqual(
         expected, res,
         'expected %s got %s with err: %s' % (expected, res, err))
Ejemplo n.º 14
0
 def test_invalid_priority_out_of_range(self, test_name, priority,
                                        expected):
     """Rule with priority set to various values."""
     test_rule = generate_ingress_rule()
     test_rule['priority'] = priority
     err = rule_validator.validate_gcp_rule(test_rule)
     res = err is None
     self.assertEqual(
         expected, res,
         'expected %s got %s with err: %s' % (expected, res, err))
Ejemplo n.º 15
0
 def test_direction_ingress_destination_ranges(self, test_name, explicit):
     """Rule with INGRESS direction + destinationRanges returns error."""
     test_rule = generate_ingress_rule()
     if explicit:
         test_rule['direction'] = 'INGRESS'
     test_rule.pop('sourceRanges')
     test_rule['destinationRanges'] = [u'10.8.0.0/24']
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsInstance(err, text,
                           'expected error message, got "%s"' % err)
Ejemplo n.º 16
0
 def test_valid_explicit_ingress(self):
     """Verify valid ingress rule with explicit direction returns None."""
     test_rule = generate_ingress_rule()
     test_rule['direction'] = 'INGRESS'
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsNone(err, 'expected no error message, got err: %s' % err)
    def add_rule(self, rule, network_name=None):
        """Adds rule to the self.rules dictionary.

        Args:
            rule (dict): A valid dict representing a GCE firewall rule
            network_name (str): If set, rules which have no network currently
                defined will have their network set to network_name, and
                network_name will be prepended to the rule name.

                Rules that do have a network defined have their network matched
                against network_name, and if they differ the rule is not added.

        Raises:
            DuplicateFirewallRuleNameError: Two or more rules have the same
                name.
            InvalidFirewallRuleError: One or more rules failed validation.
        """
        # pylint: disable=too-many-branches
        if not isinstance(rule, dict):
            raise InvalidFirewallRuleError(
                'Invalid rule type. Found %s expected dict' % type(rule))

        new_rule = self._order_lists_in_rule(rule)

        if network_name:
            if 'network' in new_rule:
                rule_network = get_network_name_from_url(new_rule['network'])
                if rule_network != network_name:
                    # Don't add the rule if it's network does not match
                    # network_name
                    LOGGER.info(
                        'Firewall rule does not apply to network %s, '
                        'skipping: %s', network_name,
                        json.dumps(new_rule, sort_keys=True))
                    return

                # Normalize network value to full network URL for rules that
                # already include a network name, so comparison with a rule
                # from the API will return True
                new_rule['network'] = build_network_url(
                    self._project, network_name)
            else:
                new_rule['network'] = build_network_url(
                    self._project, network_name)

                # Update the rule name by prepending the network, so it is
                # unique. If the new rule does not have a name defined it will
                # fail the _check_rule_before_adding validation and an
                # InvalidFirewallRuleError exception will be raised.
                if 'name' in new_rule:
                    # Truncate network name if too long. This may result in
                    # duplicate rule names, which will cause the network name
                    # to be changed to a md5 hash representation.
                    new_name = '%s-%s' % (network_name[:(
                        62 - len(new_rule['name']))], new_rule['name'])

                    while new_name in self.rules:
                        # Firewall rule names must start with [a-z], hashes
                        # could start with a number, so we prepend hn-
                        # (hashed network) to the name.
                        network_name = 'hn-' + hashlib.md5(
                            network_name.encode()).hexdigest()
                        new_name = '%s-%s' % (network_name[:(
                            62 - len(new_rule['name']))], new_rule['name'])

                    new_rule['name'] = new_name

        if 'priority' not in new_rule:
            new_rule['priority'] = self.DEFAULT_PRIORITY

        if 'direction' not in new_rule:
            new_rule['direction'] = self.DEFAULT_DIRECTION

        if 'logConfig' not in new_rule:
            new_rule['logConfig'] = self.DEFAULT_LOGCONFIG

        if 'disabled' not in new_rule:
            new_rule['disabled'] = self.DEFAULT_DISABLED

        error = rv.validate_gcp_rule(new_rule)
        if error:
            raise InvalidFirewallRuleError(error)

        if rule['name'] in self.rules:
            raise DuplicateFirewallRuleNameError(
                'Rule %s already defined in rules: %s' %
                (rule['name'], ', '.join(sorted(self.rules.keys()))))

        callback_ok = (self._add_rule_callback(new_rule)
                       if self._add_rule_callback else True)
        if callback_ok:
            self.rules[new_rule['name']] = new_rule
Ejemplo n.º 18
0
 def test_valid_egress(self):
     """Verify valid egress rules returns None."""
     test_rule = generate_egress_rule()
     err = rule_validator.validate_gcp_rule(test_rule)
     self.assertIsNone(err, 'expected no error message, got err: %s' % err)