func()

in internal/scanners/defender.go [63:134]


func (s *DefenderScanner) GetRecommendations(ctx context.Context, scan bool, cred azcore.TokenCredential, subscriptions map[string]string, filters *models.Filters) []models.DefenderRecommendation {
	models.LogResourceTypeScan("Defender Recommendations")
	resources := []models.DefenderRecommendation{}

	if scan {
		graphClient := graph.NewGraphQuery(cred)
		query := `
		SecurityResources
		| where type == 'microsoft.security/assessments'
		| where properties.status.code == 'Unhealthy'
		| mvexpand Category = properties.metadata.categories
		| extend
			AssessmentId = id,
			AssessmentKey = name,
			ResourceId = properties.resourceDetails.Id,
			ResourceIdsplit = split(properties.resourceDetails.Id, '/'),
			RecommendationName = properties.displayName,
			RecommendationState = properties.status.code,
			ActionDescription = properties.metadata.description,
			RemediationDescription = properties.metadata.remediationDescription,
			RecommendationSeverity = properties.metadata.severity,
			PolicyDefinitionId = properties.metadata.policyDefinitionId,
			AssessmentType = properties.metadata.assessmentType,
			Threats = properties.metadata.threats,
			UserImpact = properties.metadata.userImpact,
			AzPortalLink = tostring(properties.links.azurePortal)
		| extend
			ResourceSubId = tostring(ResourceIdsplit[2]),
			ResourceGroupName = tostring(ResourceIdsplit[4]),
			ResourceType = tostring(ResourceIdsplit[6]),
			ResourceName = tostring(ResourceIdsplit[8])
		| join kind=leftouter (resourcecontainers
			| where type == 'microsoft.resources/subscriptions'
			| project SubscriptionName = name, subscriptionId) on subscriptionId
		| project SubscriptionId=subscriptionId, SubscriptionName, ResourceGroupName, ResourceType,
			ResourceName, Category, RecommendationSeverity, RecommendationName, ActionDescription,
			RemediationDescription, AzPortalLink, ResourceId
	`
		log.Debug().Msg(query)
		subs := make([]*string, 0, len(subscriptions))
		for s := range subscriptions {
			subs = append(subs, &s)
		}
		result := graphClient.Query(ctx, query, subs)
		resources = []models.DefenderRecommendation{}
		if result.Data != nil {
			for _, row := range result.Data {
				m := row.(map[string]interface{})

				if filters.Azqr.IsServiceExcluded(to.String(m["ResourceId"])) {
					continue
				}

				resources = append(resources, models.DefenderRecommendation{
					SubscriptionId:         to.String(m["SubscriptionId"]),
					SubscriptionName:       to.String(m["SubscriptionName"]),
					ResourceGroupName:      to.String(m["ResourceGroupName"]),
					ResourceType:           to.String(m["ResourceType"]),
					ResourceName:           to.String(m["ResourceName"]),
					Category:               to.String(m["Category"]),
					RecommendationSeverity: to.String(m["RecommendationSeverity"]),
					RecommendationName:     to.String(m["RecommendationName"]),
					ActionDescription:      to.String(m["ActionDescription"]),
					RemediationDescription: to.String(m["RemediationDescription"]),
					AzPortalLink:           fmt.Sprintf("https://%s", to.String(m["AzPortalLink"])),
					ResourceId:             to.String(m["ResourceId"]),
				})
			}
		}
	}
	return resources
}