Example #1
0
 def validate(self):
     super(PHDMode, self).validate()
     if self.policy.resource_type == 'account':
         return
     if 'health-event' not in self.policy.resource_manager.filter_registry:
         raise PolicyValidationError(
             "policy:%s phd event mode not supported for resource:%s" %
             (self.policy.name, self.policy.resource_type))
Example #2
0
 def validate(self):
     if self.data.get('encrypted', True):
         key = self.data.get('target_key')
         if not key:
             raise PolicyValidationError(
                 "Encrypted snapshot copy requires kms key on %s" %
                 (self.manager.data, ))
     return self
Example #3
0
    def factory(self, data, manager):
        if isinstance(data, dict):
            action_type = data.get('type')
            if action_type is None:
                raise PolicyValidationError("Invalid action type found in %s" %
                                            (data))
        else:
            action_type = data
            data = {}

        action_class = self.get(action_type)
        if action_class is None:
            raise PolicyValidationError(
                "Invalid action type %s, valid actions %s" %
                (action_type, list(self.keys())))
        # Construct a ResourceManager
        return action_class(data, manager).validate()
Example #4
0
 def parse(cls, data):
     results = []
     for d in data:
         if not isinstance(d, dict):
             raise PolicyValidationError(
                 "Health Query Filter Invalid structure %s" % d)
         results.append(cls(d).validate())
     return results
Example #5
0
 def validate(self):
     attrs = dict(self.data['attributes'])
     if 'DBClusterIdentifier' in attrs:
         raise PolicyValidationError(
             "Can't include DBClusterIdentifier in modify-db-cluster action"
         )
     attrs['DBClusterIdentifier'] = 'PolicyValidation'
     return shape_validate(attrs, self.shape, 'rds')
 def validate(self):
     for finding_type in self.data["types"]:
         if finding_type.count('/') > 2 or finding_type.split(
                 '/')[0] not in FindingTypes:
             raise PolicyValidationError(
                 "Finding types must be in the format 'namespace/category/classifier'."
                 " Found {}. Valid namespace values are: {}.".format(
                     finding_type, " | ".join([ns for ns in FindingTypes])))
 def validate(self):
     attrs = dict(self.data['attributes'])
     if 'Name' in attrs:
         raise PolicyValidationError(
             "Can't include Name in update-trail action")
     attrs['Name'] = 'PolicyValidation'
     return shape_validate(attrs, self.shape,
                           self.manager.resource_type.service)
Example #8
0
 def validate(self):
     if self.data.get('state') == 'enabled':
         if 'bucket' not in self.data:
             raise PolicyValidationError(
                 ("redshift logging enablement requires `bucket` "
                  "and `prefix` specification on %s" %
                  (self.manager.data, )))
     return self
Example #9
0
 def validate(self):
     for f in self.manager.iter_filters():
         if isinstance(f, RedshiftSnapshotCrossAccount):
             return self
     raise PolicyValidationError(
         '`revoke-access` may only be used in '
         'conjunction with `cross-account` filter on %s' %
         (self.manager.data, ))
 def validate(self):
     region = self.manager.data.get('region', '')
     if len(self.global_services.intersection(self.data.get('services', []))):
         if region != 'us-east-1':
             raise PolicyValidationError(
                 "Global services: %s must be targeted in us-east-1 on the policy"
                 % ', '.join(self.global_services))
     return self
Example #11
0
 def _validate_event_matches_resource(self):
     resource_type = self.policy.resource_manager.resource_type.resource_type
     if resource_type != 'armresource':
         for event in self.subscribed_events:
             if resource_type.lower() not in event.lower():
                 raise PolicyValidationError(
                     'The policy resource, {}, can not be triggered by the event, {}.'
                     .format(resource_type, event))
Example #12
0
def shape_validate(params, shape_name, service):
    session = fake_session()._session
    model = session.get_service_model(service)
    shape = model.shape_for(shape_name)
    validator = ParamValidator()
    report = validator.validate(params, shape)
    if report.has_errors():
        raise PolicyValidationError(report.generate_report())
Example #13
0
 def validate_policy(self, p):
     if not isinstance(p, dict):
         raise PolicyValidationError(
             ('policy must be a dictionary/mapping found:%s policy:\n %s' %
              (type(p).__name__, json.dumps(p, indent=2))))
     pkeys = set(p)
     if self.required_policy_keys.difference(pkeys):
         raise PolicyValidationError(
             'policy missing required keys (name, resource) data:\n %s' %
             (json.dumps(p, indent=2)))
     if pkeys.difference(self.allowed_policy_keys):
         raise PolicyValidationError(
             'policy:%s has unknown keys: %s' % (p['name'], ','.join(
                 pkeys.difference(self.allowed_policy_keys))))
     if not isinstance(p.get('filters', []), (list, type(None))):
         raise PolicyValidationError(
             ('policy:%s must use a list for filters found:%s' %
              (p['name'], type(p['filters']).__name__)))
     element_types = (dict, str)
     for f in p.get('filters', ()):
         if not isinstance(f, element_types):
             raise PolicyValidationError(
                 ('policy:%s filter must be a mapping/dict found:%s' %
                  (p.get('name', 'unknown'), type(f).__name__)))
     if not isinstance(p.get('actions', []), (list, type(None))):
         raise PolicyValidationError(
             ('policy:%s must use a list for actions found:%s' %
              (p.get('name', 'unknown'), type(p['actions']).__name__)))
     for a in p.get('actions', ()):
         if not isinstance(a, element_types):
             raise PolicyValidationError(
                 ('policy:%s action must be a mapping/dict found:%s' %
                  (p.get('name', 'unknown'), type(a).__name__)))
Example #14
0
 def validate(self):
     super().validate()
     if not self.policy.data['mode'].get('schedule'):
         raise PolicyValidationError(
             "policy:%s config-poll-rule schedule required" %
             (self.policy.name))
     if self.policy.resource_manager.resource_type.config_type:
         raise PolicyValidationError(
             "resource:%s fully supported by config and should use mode: config-rule"
             % (self.policy.resource_type))
     if self.policy.data['mode'].get('pattern'):
         raise PolicyValidationError(
             "policy:%s AWS Config does not support event pattern filtering"
             % (self.policy.name))
     if not self.policy.resource_manager.resource_type.cfn_type:
         raise PolicyValidationError(
             ('policy:%s resource:%s does not have a cloudformation type'
              ' and is there-fore not supported by config-poll-rule'))
Example #15
0
    def validate(self):
        if not len(list(self.data.keys())) == 1:
            raise PolicyValidationError("EMR Query Filter Invalid %s" %
                                        self.data)
        self.key = list(self.data.keys())[0]
        self.value = list(self.data.values())[0]

        if self.key not in EMR_VALID_FILTERS and not self.key.startswith(
                'tag:'):
            raise PolicyValidationError(
                "EMR Query Filter invalid filter name %s" % (self.data))

        if self.value is None:
            raise PolicyValidationError(
                "EMR Query Filters must have a value, use tag-key"
                " w/ tag name as value for tag present checks"
                " %s" % self.data)
        return self
 def validate(self):
     delta = set(self.data.keys()).difference(self.multi_attrs)
     delta.remove('type')
     if 'match-operator' in delta:
         delta.remove('match-operator')
     if delta:
         raise PolicyValidationError(
             "filter:{} unknown keys {} on {}".format(
                 self.type, ", ".join(delta), self.manager.data))
Example #17
0
def lifecycle_rule_validate(policy, rule):
    # This is a non exhaustive list of lifecycle validation rules
    # see this for a more comprehensive list
    #
    # https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html#lp_evaluation_rules

    if (rule['selection']['tagStatus'] == 'tagged' and
            'tagPrefixList' not in rule['selection']):
        raise PolicyValidationError(
            ("{} has invalid lifecycle rule {} tagprefixlist "
             "required for tagStatus: tagged").format(
                 policy.name, rule))
    if (rule['selection']['countType'] == 'sinceImagePushed' and
            'countUnit' not in rule['selection']):
        raise PolicyValidationError(
            ("{} has invalid lifecycle rule {} countUnit "
             "required for countType: sinceImagePushed").format(
                 policy.name, rule))
Example #18
0
 def validate(self):
     if 'mode' in self.data['policy']:
         raise PolicyValidationError("Execution mode can't be specified in "
                                     "embedded policy %s" % self.data)
     if 'actions' in self.data['policy']:
         raise PolicyValidationError("Actions can't be specified in "
                                     "embedded policy %s" % self.data)
     collection = PolicyLoader(self.manager.config).load_data(
         {'policies': [self.data['policy']]},
         "memory://",
         session_factory=self.manager.session_factory)
     if not collection:
         raise PolicyValidationError(
             "policy %s missing filter empty embedded policy" %
             (self.manager.ctx.policy.name))
     self.embedded_policy = list(collection).pop()
     self.embedded_policy.validate()
     return self
Example #19
0
 def validate(self):
     if not self.data.get('state', True):
         return self
     key = self.data.get('kms-key', '')
     if not key:
         raise ValueError('Must specify either a KMS key ARN or Alias')
     if 'alias/' not in key and ':key/' not in key:
         raise PolicyValidationError("Invalid kms key format %s" % key)
     return self
Example #20
0
    def parse(cls, data):
        filters = []
        if not isinstance(data, (tuple, list)):
            raise PolicyValidationError(
                "%s Query invalid format, must be array of dicts %s" % (
                    cls.type_name,
                    data))
        for d in data:
            if not isinstance(d, dict):
                raise PolicyValidationError(
                    "%s Query Filter Invalid %s" % (cls.type_name, data))
            if "Name" not in d or cls.value_key not in d:
                raise PolicyValidationError(
                    "%s Query Filter Invalid: Missing Key or Values in %s" % (
                        cls.type_name, data))

            key = d['Name']
            values = d[cls.value_key]

            if not cls.multi_value and isinstance(values, list):
                raise PolicyValidationError(
                    "%s Query Filter Invalid Key: Value:%s Must be single valued" % (
                        cls.type_name, key))
            elif not cls.multi_value:
                values = [values]

            if key not in cls.QuerySchema and not key.startswith('tag:'):
                raise PolicyValidationError(
                    "%s Query Filter Invalid Key:%s Valid: %s" % (
                        cls.type_name, key, ", ".join(cls.QuerySchema.keys())))

            vtype = cls.QuerySchema.get(key)
            if vtype is None and key.startswith('tag'):
                vtype = str

            if not isinstance(values, list):
                raise PolicyValidationError(
                    "%s Query Filter Invalid Values, must be array %s" % (
                        cls.type_name, data,))

            for v in values:
                if isinstance(vtype, tuple):
                    if v not in vtype:
                        raise PolicyValidationError(
                            "%s Query Filter Invalid Value: %s Valid: %s" % (
                                cls.type_name, v, ", ".join(vtype)))
                elif not isinstance(v, vtype):
                    raise PolicyValidationError(
                        "%s Query Filter Invalid Value Type %s" % (
                            cls.type_name, data,))

            filters.append(d)

        return filters
Example #21
0
    def _validate_value_regex(self, regex):
        """Specific validation for `value_regex` type

        The `value_regex` type works a little differently.  In
        particular it doesn't support OPERATORS that perform
        operations on a list of values, specifically 'intersect',
        'contains', 'difference', 'in' and 'not-in'
        """
        # Sanity check that we can compile
        try:
            pattern = re.compile(regex)
            if pattern.groups != 1:
                raise PolicyValidationError(
                    "value_regex must have a single capturing group: %s" %
                    self.data)
        except re.error as e:
            raise PolicyValidationError(
                "Invalid value_regex: %s %s" % (e, self.data))
        return self
Example #22
0
 def _handle_missing_resources(self, policy_data, missing):
     # for an invalid resource type catch and try to associate
     # it to the policy by name.
     for p in policy_data.get('policies', ()):
         pr = p['resource']
         if '.' not in pr:
             pr = "aws.%s" % pr
         if pr in missing:
             raise PolicyValidationError(
                 "Policy:%s references an unknown resource:%s" %
                 (p['name'], p['resource']))
Example #23
0
 def resource_query(self):
     filters = []
     for q in self.data.get('query', ()):
         if (not isinstance(q, dict) or not set(q.keys()) == set(
             ('Key', 'Values', 'Operator'))
                 or q['Key'] not in self.QueryKeys
                 or q['Operator'] not in self.QueryOperators):
             raise PolicyValidationError("invalid ops-item query %s" %
                                         self.data['query'])
         filters.append(q)
     return {'OpsItemFilters': filters}
Example #24
0
 def validate(self):
     if 'accounts' in self.data and self.data['accounts'] == 'matched':
         found = False
         for f in self.manager.iter_filters():
             if isinstance(f, AmiCrossAccountFilter):
                 found = True
                 break
         if not found:
             raise PolicyValidationError(
                 "policy:%s filter:%s with matched requires cross-account filter"
                 % (self.manager.ctx.policy.name, self.type))
Example #25
0
 def validate(self):
     m = self.get_execution_mode()
     if m is None:
         raise PolicyValidationError(
             "Invalid Execution mode in policy %s" % (self.data,))
     m.validate()
     self.validate_policy_start_stop()
     for f in self.resource_manager.filters:
         f.validate()
     for a in self.resource_manager.actions:
         a.validate()
Example #26
0
 def validate(self):
     mode = self.policy.data['mode']
     if 'tz' in mode:
         error = PolicyValidationError(
             "policy:%s gcp-periodic invalid tz:%s" %
             (self.policy.name, mode['tz']))
         # We can't catch all errors statically, our local tz retrieval
         # then the form gcp is using, ie. not all the same aliases are
         # defined.
         tzinfo = tz.gettz(mode['tz'])
         if tzinfo is None:
             raise error
Example #27
0
 def validate(self):
     if self.data['accounts'] != 'matched':
         return
     found = False
     for f in self.manager.iter_filters():
         if isinstance(f, CatalogPortfolioCrossAccount):
             found = True
             break
     if not found:
         raise PolicyValidationError(
             "policy:%s action:%s with matched requires cross-account filter"
             % (self.manager.ctx.policy.name, self.type))
Example #28
0
    def validate(self):

        if self.manager.data.get('mode', {}).get('type') == 'azure-event-grid' \
                and self.data.get('days') is not None:
            raise PolicyValidationError(
                "Auto tag actions in event mode does not use days.")

        if (self.data.get('days') is not None and
                (self.data.get('days') < 1 or self.data.get('days') > 90)):
            raise FilterValidationError("Days must be between 1 and 90")

        return self
Example #29
0
 def validate(self):
     found = False
     for f in self.manager.iter_filters():
         if isinstance(f, WafEnabled):
             found = True
             break
     if not found:
         # try to ensure idempotent usage
         raise PolicyValidationError(
             "set-waf should be used in conjunction with waf-enabled filter on %s"
             % (self.manager.data, ))
     return self
Example #30
0
 def validate(self):
     sg_filter = self.manager.filter_registry.get('security-group')
     if not sg_filter or not sg_filter.RelatedIdsExpression:
         raise PolicyValidationError(self._format_error((
             "policy:{policy} resource:{resource_type} does "
             "not support {action_type} action")))
     if self.get_action_group_names():
         vpc_filter = self.manager.filter_registry.get('vpc')
         if not vpc_filter or not vpc_filter.RelatedIdsExpression:
             raise PolicyValidationError(self._format_error((
                 "policy:{policy} resource:{resource_type} does not support "
                 "security-group names only ids in action:{action_type}")))
         self.vpc_expr = jmespath.compile(vpc_filter.RelatedIdsExpression)
     if self.sg_expr is None:
         self.sg_expr = jmespath.compile(
             self.manager.filter_registry.get('security-group').RelatedIdsExpression)
     if 'all' in self._get_array('remove') and not self._get_array('isolation-group'):
         raise PolicyValidationError(self._format_error((
             "policy:{policy} use of action:{action_type} with "
             "remove: all requires specifying isolation-group")))
     return self