All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.atlassian.maven.plugins.aws.it.Executor.kt Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
package com.atlassian.maven.plugins.aws.it

import com.amazonaws.services.ec2.model.Instance
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement
import com.amazonaws.services.simplesystemsmanagement.model.CommandStatus
import com.amazonaws.services.simplesystemsmanagement.model.CommandStatus.*
import com.amazonaws.services.simplesystemsmanagement.model.ListCommandsRequest
import com.amazonaws.services.simplesystemsmanagement.model.SendCommandRequest
import org.apache.maven.plugin.logging.Log

class Executor(
    private val systemsManagement: AWSSimpleSystemsManagement,
    private val log: Log
) {
    fun execute(
        steps: List,
        instances: List
    ) {
        steps.forEach { step ->
            execute(step, instances)
        }
    }

    private fun execute(
        step: ProperExecutionStep,
        instances: List
    ) {
        val request = SendCommandRequest().withDocumentName("AWS-RunShellScript")
            .withParameters(
                mapOf(
                    "commands" to step.commands
                )
            )
            .withInstanceIds(matchInstanceIds(step.target, instances))
            .withTimeoutSeconds(step.timeout.seconds.toInt())
            .withOutputS3BucketName("aws-integration-test-plugin")
            .withOutputS3KeyPrefix("executor-output")
        try {
            log.info("Executing $request")
            val command = systemsManagement.sendCommand(request).command
            log.info("Awaiting termination of $command")
            awaitTermination(command.commandId)
        } catch (e: Exception) {
            val message = "Failed to execute $request, " +
                "see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/systems-manager-prereqs.html " +
                "and https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/troubleshooting-remote-commands.html"
            throw RuntimeException(message, e)
        }
    }

    private fun awaitTermination(
        commandId: String
    ) {
        val terminalStates = setOf(
            Cancelled,
            Failed,
            Success,
            TimedOut
        )
        while (true) {
            val status = pollStatus(commandId)
            if (terminalStates.contains(status)) {
                if (status == Success) {
                    log.info("$commandId successfully terminated")
                    break
                } else {
                    throw RuntimeException("$commandId unsuccessfully terminated")
                }
            } else {
                log.info("$commandId did not terminate yet")
                Thread.sleep(5000)
            }
        }
    }

    private fun pollStatus(
        commandId: String
    ): CommandStatus {
        val command = systemsManagement
            .listCommands(ListCommandsRequest().withCommandId(commandId))
            .commands
            .first()
        log.info("Polled $command")
        return CommandStatus.fromValue(command.status)
    }

    private fun matchInstanceIds(
        target: ResourceTag,
        instances: Collection
    ): List {
        return instances
            .filter {
                it.tags.any {
                    it.key == target.key && it.value == target.value
                }
            }
            .map { it.instanceId }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy