hq/app/aws/support/TrustedAdvisor.scala (99 lines of code) (raw):
package aws.support
import aws.AwsAsyncHandler.{asScala, handleAWSErrs}
import aws.{AwsClient, AwsClients}
import logic.DateUtils.fromISOString
import model._
import utils.attempt.{Attempt, FailedAttempt, Failure}
import scala.jdk.CollectionConverters._
import scala.concurrent.ExecutionContext
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.support.SupportAsyncClient
import software.amazon.awssdk.services.support.model._
object TrustedAdvisor {
val portPriorityMap =
Seq(
"FTP" -> Set(20, 21),
"Postgres" -> Set(5432),
"MySQL" -> Set(3306),
"Redshift" -> Set(5439),
"MongoDB" -> Set(27017, 27018, 27019),
"Redis" -> Set(6379, 6380),
"MSQL" -> Set(4333),
"Oracle DB" -> Set(5500),
"SQL Server" -> Set(1433, 1434),
"RDP" -> Set(3389),
"Play FW" -> Set(9000),
"Spark" -> Set(7077, 4040, 4041, 4042),
"EMR" -> Set(8890),
"Spark Web" -> Set(8080),
"Kibana" -> Set(5601),
"Elastic Search" -> Set(9200, 9300),
"SSH" -> Set(22)
)
val indexedPortMap = portPriorityMap.zipWithIndex
val alertLevelMapping = Map("Red" -> 0, "Yellow" -> 1, "Green" -> 2)
// SHOW ALL TRUSTED ADVISOR CHECKS
def getTrustedAdvisorChecks(client: AwsClient[SupportAsyncClient])(implicit ec: ExecutionContext): Attempt[List[TrustedAdvisorCheck]] = {
val request = DescribeTrustedAdvisorChecksRequest.builder.language("en").build()
handleAWSErrs(client)(asScala(client.client.describeTrustedAdvisorChecks(request))).map(parseTrustedAdvisorChecksResponse)
}
def refreshTrustedAdvisorChecks(client: AwsClient[SupportAsyncClient], checkId: String)(implicit ec: ExecutionContext): Attempt[RefreshTrustedAdvisorCheckResponse] = {
val request = RefreshTrustedAdvisorCheckRequest.builder.checkId(checkId).build()
handleAWSErrs(client)(asScala(client.client.refreshTrustedAdvisorCheck(request)))
}
def parseTrustedAdvisorChecksResponse(result: DescribeTrustedAdvisorChecksResponse): List[TrustedAdvisorCheck] = {
result.checks.asScala.toList.map { trustedAdvisorCheckResult =>
TrustedAdvisorCheck(
id = trustedAdvisorCheckResult.id,
name = trustedAdvisorCheckResult.name,
description = trustedAdvisorCheckResult.description,
category = trustedAdvisorCheckResult.category
)
}
}
// GENERIC FUNCTIONALITY FOR DETAILED CHECK RESULTS
def getTrustedAdvisorCheckDetails(client: AwsClient[SupportAsyncClient], checkId: String)(implicit ec: ExecutionContext): Attempt[DescribeTrustedAdvisorCheckResultResponse] = {
val request = DescribeTrustedAdvisorCheckResultRequest.builder
.language("en")
.checkId(checkId)
.build()
handleAWSErrs(client)(asScala(client.client.describeTrustedAdvisorCheckResult(request)))
}
private[support] def findPortPriorityIndex(port: String) = {
Option(port).flatMap { case p if p.trim.nonEmpty =>
val allPorts = p.trim.split("-").map(_.toInt).toList match {
case head :: tail :: Nil => (head to tail).toSet
case head :: Nil => Set(head)
case _ => Set.empty[Int]
}
indexedPortMap.collectFirst {
case ((_, seq), idx) if allPorts.diff(seq) != allPorts => idx
}
}
}
private[support] def sortSecurityFlags[A <: TrustedAdvisorCheckDetails](list: List[A]): List[A] = {
list.sortWith {
case (a: RDSSGsDetail, b: RDSSGsDetail) =>
alertLevelMapping.getOrElse(a.alertLevel, 1) < alertLevelMapping.getOrElse(b.alertLevel, 1)
case (a: SGOpenPortsDetail, b: SGOpenPortsDetail) =>
if (a.alertLevel == b.alertLevel) {
findPortPriorityIndex(a.port).getOrElse(999) < findPortPriorityIndex(b.port).getOrElse(999)
} else
alertLevelMapping.getOrElse(a.alertLevel, 2) < alertLevelMapping.getOrElse(b.alertLevel, 2)
case (_, _) => false
}
}
def parseTrustedAdvisorCheckResult[A <: TrustedAdvisorCheckDetails](parseDetails: TrustedAdvisorResourceDetail => Attempt[A], ec: ExecutionContext)(response: DescribeTrustedAdvisorCheckResultResponse): Attempt[TrustedAdvisorDetailsResult[A]] = {
implicit val executionContext: ExecutionContext = ec
val result = response.result
for {
resources <- Attempt.traverse(result.flaggedResources.asScala.toList)(parseDetails)
} yield TrustedAdvisorDetailsResult(
checkId = result.checkId,
status = result.status,
timestamp = fromISOString(result.timestamp),
flaggedResources = sortSecurityFlags(resources),
resourcesIgnored = result.resourcesSummary.resourcesIgnored,
resourcesFlagged = result.resourcesSummary.resourcesFlagged,
resourcesSuppressed = result.resourcesSummary.resourcesSuppressed
)
}
}