app/collectors/image.scala (96 lines of code) (raw):

package collectors import agent._ import conf.AWS import controllers.routes import org.joda.time.DateTime import play.api.mvc.Call import software.amazon.awssdk.services.ec2.Ec2Client import software.amazon.awssdk.services.ec2.model.{ DescribeImagesRequest, Filter, Image => AwsImage } import utils.Logging import scala.jdk.CollectionConverters._ import scala.language.postfixOps import scala.util.Try class ImageCollectorSet(accounts: Accounts) extends CollectorSet[Image]( ResourceType("images"), accounts, Some(Regional) ) { val lookupCollector: PartialFunction[Origin, Collector[Image]] = { case amazon: AmazonOrigin => AWSImageCollector(amazon, resource, amazon.crawlRate(resource.name)) } } case class AWSImageCollector( origin: AmazonOrigin, resource: ResourceType, crawlRate: CrawlRate ) extends Collector[Image] with Logging { val client: Ec2Client = Ec2Client.builder .credentialsProvider(origin.credentials.provider) .region(origin.awsRegionV2) .overrideConfiguration(AWS.clientConfig) .build def crawl: Iterable[Image] = { val ownerIdFilter = Filter.builder.name("owner-id").values(origin.accountNumber.get).build val imageTypeFilter = Filter.builder.name("image-type").values("machine").build val result = client.describeImages( DescribeImagesRequest.builder .filters( ownerIdFilter, imageTypeFilter ) .build ) result.images.asScala.map(Image.fromApiData(_, origin.region)) } } object Image { def arn(region: String, imageId: String) = s"arn:aws:ec2:$region::image/$imageId" def fromApiData(image: AwsImage, regionName: String): Image = { Image( arn = arn(regionName, image.imageId), name = Option(image.name), imageId = image.imageId, region = regionName, description = Option(image.description), tags = image.tags.asScala.map(t => t.key -> t.value).toMap, creationDate = Try(new DateTime(image.creationDate)).toOption, state = image.stateAsString, architecture = image.architectureAsString, ownerId = image.ownerId, virtualizationType = image.virtualizationTypeAsString, hypervisor = image.hypervisorAsString, sriovNetSupport = Option(image.sriovNetSupport), rootDeviceType = image.rootDeviceTypeAsString, imageType = image.imageTypeAsString ) } } case class Image( arn: String, name: Option[String], imageId: String, region: String, description: Option[String], tags: Map[String, String], creationDate: Option[DateTime], state: String, architecture: String, ownerId: String, virtualizationType: String, hypervisor: String, sriovNetSupport: Option[String], rootDeviceType: String, imageType: String ) extends IndexedItem { def callFromArn: (String) => Call = arn => routes.Api.image(arn) }