예제 #1
0
 def validate(self):
     super(LambdaMode, self).validate()
     prefix = self.policy.data['mode'].get('function-prefix', 'custodian-')
     if len(prefix + self.policy.name) > 64:
         raise PolicyValidationError(
             "Custodian Lambda policies have a max length with prefix of 64"
             " policy:%s prefix:%s" % (prefix, self.policy.name))
     tags = self.policy.data['mode'].get('tags')
     if not tags:
         return
     reserved_overlap = [t for t in tags if t.startswith('custodian-')]
     if reserved_overlap:
         log.warning(('Custodian reserves policy lambda '
                      'tags starting with custodian - policy specifies %s' %
                      (', '.join(reserved_overlap))))
예제 #2
0
    def validate(self, data):
        if not isinstance(data, dict):
            raise PolicyValidationError(
                ("Policy file top level data structure "
                 "should be a mapping/dict, instead found:%s"
                 "") % (type(data).__name__))
        dkeys = set(data.keys())

        extra = dkeys.difference(self.allowed_file_keys)
        if extra:
            raise PolicyValidationError(
                ('Policy files top level keys are %s, found extra: %s' %
                 (', '.join(self.allowed_file_keys), ', '.join(extra))))

        if 'policies' not in data:
            raise PolicyValidationError("`policies` list missing")

        pdata = data.get('policies', [])
        if not isinstance(pdata, list):
            raise PolicyValidationError(
                ('`policies` key should be an array/list found: %s' %
                 (type(pdata).__name__)))
        for p in pdata:
            self.validate_policy(p)
예제 #3
0
 def validate(self):
     super().validate()
     identity = jmespath.search('mode."provision-options".identity',
                                self.policy.data)
     if (identity and identity['type'] == AUTH_TYPE_UAI
             and 'id' not in identity):
         raise PolicyValidationError(
             "policy:%s user assigned identity requires specifying id" %
             (self.policy.name))
     if not identity or identity['type'] == AUTH_TYPE_EMBED:
         self.log.error(
             ('policy:%s function policies should use UserAssigned Identities '
              'see https://cloudcustodian.io/docs/azure/configuration/functionshosting.html#authentication-options'
              ),  # noqa
             self.policy.name)
예제 #4
0
    def validate(self):

        if self.manager.action_registry.get('tag') is None:
            raise FilterValidationError("Resource does not support tagging")

        if self.manager.data.get('mode', {}).get('type') == 'azure-event-grid' \
                and self.data.get('days') is not None:
            raise PolicyValidationError(
                "Auto tag user 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
예제 #5
0
    def validate(self):
        attrs = dict(self.data.get('attributes'))
        if attrs.get('CallerReference'):
            raise PolicyValidationError(
                'CallerReference field cannot be updated')

        # Set default values for required fields if they are not present
        attrs["CallerReference"] = ""
        self.set_required_update_fields(attrs)
        request = {
            "DistributionConfig": attrs,
            "Id": "sample_id",
            "IfMatch": "sample_string",
        }
        return shape_validate(request, self.shape, 'cloudfront')
예제 #6
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))
    if (rule['selection']['countType'] == 'imageCountMoreThan' and
            'countUnit' in rule['selection']):
        raise PolicyValidationError(
            ("{} has invalid lifecycle rule {} countUnit "
             "invalid for countType: imageCountMoreThan").format(
                 policy.name, rule))
예제 #7
0
 def validate(self):
     if not self.data.get('matched'):
         return
     listeners = [
         f for f in self.manager.filters if isinstance(f, self.__class__)
     ]
     found = False
     for f in listeners[:listeners.index(self)]:
         if not f.data.get('matched', False):
             found = True
             break
     if not found:
         raise PolicyValidationError(
             "matched listener filter, requires preceding listener filter on %s "
             % (self.manager.data, ))
     return self
예제 #8
0
    def validate(self, config_name, shape):
        attrs = dict(self.data.get('attributes'))
        if attrs.get('CallerReference'):
            raise PolicyValidationError('CallerReference field cannot be updated')

        # Set default values for required fields if they are not present
        attrs["CallerReference"] = ""
        config = self.validation_config
        updatedConfig = {**config, **attrs}

        request = {
            config_name: updatedConfig,
            "Id": "sample_id",
            "IfMatch": "sample_string",
        }
        return shape_validate(request, shape, 'cloudfront')
예제 #9
0
    def process(self, subscriptions):
        self.session = local_session(self.manager.session_factory)
        self.policyClient = self.session.client(
            "azure.mgmt.resource.policy.PolicyClient")

        self.scope = '/subscriptions/' + self.session.subscription_id + \
                     '/' + self.data.get('scope', '')
        self.policyDefinition = self._get_definition_id(
            self.policyDefinitionName)
        if self.policyDefinition is None:
            raise PolicyValidationError(
                "Azure Policy Definition '%s' not found." %
                (self.policyDefinitionName))

        for s in subscriptions:
            self._add_policy(s)
예제 #10
0
    def validate(self):
        shape_validate(self.data['command'], self.shape, 'ssm')
        # If used against an ec2 resource, require an ssm status filter
        # to ensure that we're not trying to send commands to instances
        # that aren't in ssm.
        if self.manager.type != 'ec2':
            return

        found = False
        for f in self.manager.iter_filters():
            if f.type == 'ssm':
                found = True
                break
        if not found:
            raise PolicyValidationError(
                "send-command requires use of ssm filter on ec2 resources")
예제 #11
0
    def parse(cls, data):
        filters = []

        if not isinstance(data, (tuple, list)):
            raise PolicyValidationError(
                "EBS Query invalid format, must be array of dicts %s" % (data))
        for d in data:
            if not isinstance(d, dict):
                raise PolicyValidationError("EBS Query Filter Invalid %s" %
                                            data)
            if "Name" not in d or "Values" not in d:
                raise PolicyValidationError(
                    "EBS Query Filter Invalid Missing Key, Values in %s" %
                    data)
            key = d['Name']
            values = d['Values']

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

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

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

            for v in values:
                if isinstance(vtype, tuple) and vtype != six.string_types:
                    if v not in vtype:
                        raise PolicyValidationError(
                            "EBS Query Filter Invalid Value: %s Valid: %s" %
                            (v, ", ".join(vtype)))
                elif not isinstance(v, vtype):
                    raise PolicyValidationError(
                        "EBS Query Filter Invalid Value Type %s" % (data, ))

            filters.append(d)

        return filters
예제 #12
0
    def load_data(self,
                  policy_data,
                  file_uri,
                  validate=None,
                  session_factory=None,
                  config=None):
        self.structure.validate(policy_data)

        # Use passed in policy exec configuration or default on loader
        config = config or self.policy_config

        # track policy resource types and only load if needed.
        rtypes = set(self.structure.get_resource_types(policy_data))

        missing = load_resources(list(rtypes))
        if missing:
            self._handle_missing_resources(policy_data, missing)

        if validate is not False or (validate is None
                                     and self.default_schema_validate):
            errors = self.validator.validate(policy_data, tuple(rtypes))
            if errors:
                raise PolicyValidationError(
                    "Failed to validate policy %s\n %s\n" %
                    (errors[1], errors[0]))

        collection = self.collection_class.from_data(policy_data, config,
                                                     session_factory)

        # non schema validation of policies isnt optional its
        # become a lazy initialization point for resources.
        #
        # it would be good to review where we do validation
        # as we also have to do after provider policy
        # initialization due to the region expansion.
        #
        # ie we should defer this to callers
        # [p.validate() for p in collection]
        return collection
예제 #13
0
 def parse(cls, data):
     results = []
     names = set()
     for d in data:
         if not isinstance(d, dict):
             raise PolicyValidationError(
                 "Job Query Filter Invalid structure %s" % d)
         for k, v in d.items():
             if isinstance(v, list):
                 raise ValueError('Job query filter invalid structure %s' %
                                  v)
         query = cls(d).validate().query()
         if query['Name'] in names:
             # Cannot filter multiple times on the same key
             continue
         names.add(query['Name'])
         if isinstance(query['Value'], list):
             results.append({query['Name']: query['Value'][0]})
             continue
         results.append({query['Name']: query['Value']})
     if 'StatusEquals' not in names:
         # add default StatusEquals if not included
         results.append({'Name': 'StatusEquals', 'Value': 'InProgress'})
     return results
예제 #14
0
 def validate(self):
     if 'mode' not in self.manager.data:
         raise PolicyValidationError(
             "Event filters can only be used with lambda policies in %s" % (
                 self.manager.data,))
     return self
예제 #15
0
 def validate(self):
     if self.data.get('key') and self.data.get('tag'):
         raise PolicyValidationError(
             "Can't specify both key and tag, choose one in %s" %
             (self.manager.data, ))
     return self
예제 #16
0
 def validate(self):
     if self.retention < 0 or self.retention > 365:
         raise PolicyValidationError(
             'attribute: retention can not be less than 0 or greater than 365'
         )
예제 #17
0
 def validate(self):
     if not any([self.data.get(k) for k in ('source', 'org-domain', 'org-id')]):
         raise PolicyValidationError(
             "policy:%s CSCC post-finding requires one of source, org-domain, org-id" % (
                 self.manager.ctx.policy.name))
예제 #18
0
 def validate(self):
     for q in self.queries:
         if not isinstance(q.get("records", None), (list, tuple)):
             raise PolicyValidationError(
                 "invalid static data source `records`")
예제 #19
0
 def validate(self):
     if not hasattr(self.manager.resource_type, 'resource_type'):
         raise PolicyValidationError(
             "%s is not supported with the Azure Resource Graph source." %
             self.manager.data['resource'])
예제 #20
0
 def validate(self):
     if self.data.get('name') not in self.metrics:
         raise PolicyValidationError(
             "invalid shield metric %s valid:%s on %s" %
             (self.data['name'], ", ".join(
                 self.metrics), self.manager.data))
예제 #21
0
 def validate(self):
     if not self.policy.resource_manager.resource_type.get:
         raise PolicyValidationError(
             "Resource:%s does not implement retrieval method" %
             (self.policy.resource_type))
예제 #22
0
 def validate(self):
     for q in self.queries:
         if not os.path.exists(q["path"]):
             raise PolicyValidationError("invalid disk path %s" % q)
         if os.path.isdir(q["path"]) and "glob" not in q:
             raise PolicyValidationError("glob pattern required for dir")
예제 #23
0
 def validate(self):
     super(ConfigRuleMode, self).validate()
     if not self.policy.resource_manager.resource_type.config_type:
         raise PolicyValidationError(
             "policy:%s AWS Config does not support resource-type:%s" %
             (self.policy.name, self.policy.resource_type))
예제 #24
0
 def _validate_is_arm_resource(self):
     if not isinstance(self.policy.resource_manager, ArmResourceManager):
         raise PolicyValidationError(
             'The policy resource, {}, is not supported in event grid mode.'
             .format(self.policy.data['resource']))
예제 #25
0
 def validate(self):
     if self.data.get("source", "disk") not in self.source_mapping:
         raise PolicyValidationError("invalid source %s" %
                                     self.data["source"])
     self.get_source().validate()
예제 #26
0
 def validate(self):
     if not self.manager.get_model().patch:
         raise PolicyValidationError('patch attribute not defined for resource')
     return self
예제 #27
0
 def validate(self):
     if self.policyDefinition is None:
         raise PolicyValidationError(
             "Azure Policy Definition '%s' not found." % (
                 self.policyDefinitionName))