func()

in tflint-ruleset-aws-serverless/rules/aws_cloudwatch_log_group_lambda_retention.go [60:184]


func (r *AwsCloudwatchLogGroupLambdaRetentionRule) Check(runner tflint.Runner) error {

	// Gather all Lambda functions
	var functions []awsLambdaLogGroup
	err := runner.WalkResources(r.functionResourceType, func(resource *configs.Resource) error {
		function := awsLambdaLogGroup{
			resourceName:  resource.Name,
			functionName:  "",
			found:         false,
			resourceRange: resource.Config.MissingItemRange(),
		}

		// Function name attribute
		body, _, diags := resource.Config.PartialContent(&hcl.BodySchema{
			Attributes: []hcl.AttributeSchema{
				{
					Name: r.functionNameAttrName,
				},
			},
		})

		if diags.HasErrors() {
			return diags
		}

		attribute, ok := body.Attributes[r.functionNameAttrName]

		if ok {
			var value string
			err := runner.EvaluateExpr(attribute.Expr, &value, nil)
			if err != nil {
				return err
			}
			function.functionName = value
		}

		functions = append(functions, function)

		return nil
	})

	if err != nil {
		return err
	}

	// Lookup log groups
	err = runner.WalkResources(r.logGroupResourceType, func(resource *configs.Resource) error {
		body, _, diags := resource.Config.PartialContent(&hcl.BodySchema{
			Attributes: []hcl.AttributeSchema{
				{
					Name: r.nameAttrName,
				},
				{
					Name: r.retentionAttrName,
				},
			},
		})

		if diags.HasErrors() {
			return diags
		}

		// Get log group attributes

		nameAttr, ok := body.Attributes[r.nameAttrName]
		// No need to check further if there are no name, early return
		if !ok {
			return nil
		}

		var nameValue string
		err := runner.EvaluateExpr(nameAttr.Expr, &nameValue, nil)
		if err != nil {
			return err
		}

		retentionAttr, ok := body.Attributes[r.retentionAttrName]
		// No need to check further if there are no retention, early return
		if !ok {
			return nil
		}

		var retentionValue string
		err = runner.EvaluateExpr(retentionAttr.Expr, &retentionValue, nil)
		if err != nil {
			return err
		}

		// Parse log group names
		re := regexp.MustCompile(`^/aws/lambda/(.*)$`)
		m := re.FindAllStringSubmatch(nameValue, -1)
		// Log group name doesn't match pattern, early return
		if len(m) > 1 {
			return nil
		}
		functionName := m[0][1]

		for i := range functions {
			if functions[i].functionName == functionName {
				functions[i].found = true
			}
			if fmt.Sprintf("${aws_lambda_function.%s.function_name}", functions[i].resourceName) == functionName {
				functions[i].found = true
			}
		}

		return nil
	})

	if err != nil {
		return err
	}

	for _, function := range functions {
		if !function.found {
			runner.EmitIssue(
				r,
				fmt.Sprintf("\"%s\" is missing a log group with retention_in_days.", r.functionResourceType),
				function.resourceRange,
			)
		}
	}

	return nil
}