Регистрация из плагина sbt - PullRequest
0 голосов
/ 06 февраля 2019

Я использую плагин s3 resolver для sbt.

Я изменил провайдер учетных данных:

lazy val s3CredentialsProvider = {bucket: String =>
    new AWSCredentialsProviderChain(
      new EnvironmentVariableCredentialsProvider(),
      PropertyFilesCredentialProvider.create(bucket)
    )
  }

, где PropertyFilesCredentialProvider - пользовательский провайдер.

Я сделал следующее, где:

  • мы добавили ConsoleLogger, используя sbt.util.internal

  • мы добавилиSystem.out.println

.

Я опубликовал плагин и использовал его в другом плагине.Похоже, что мой плагин используется, потому что распознаватель пытается использовать разные ключи доступа каждый раз, но мы не можем видеть журналы из нашего класса.

Как мы можем добавить logging, когда у нас есть код в AutoPlugin?

Код для провайдера выглядит следующим образом:

import java.io. {File, FileInputStream, InputStream} import java.util.Properties

import com.amazonaws.auth.{AWSCredentials, AWSCredentialsProvider, BasicSessionCredentials}
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder
import com.amazonaws.services.securitytoken.model.{AssumeRoleRequest, AssumeRoleResult, Credentials}

/** Creates a credential provider that reads a `roleArn` property from a file
  * and assumes the role using STS.
  *
  * This is based on https://github.com/frugalmechanic/fm-sbt-s3-resolver/blob/master/src/main/scala/fm/sbt/S3URLHandler.scala#L84
  *
  * @param file Properties file holding the ROLE_ARN for the project.
  */
class PropertyFilesCredentialProvider(file: File)
  extends AWSCredentialsProvider {

  private val ROLE_ARN_KEY: String = "roleArn"
  private val AWS_REGION: String = "<AWS_REGION>"

  protected def getRoleArn: String = {
    val is: InputStream = new FileInputStream(file)
    try {
      val props: Properties = new Properties()
      props.load(is)
      props.getProperty(ROLE_ARN_KEY)
    } finally is.close()
  }

  def createAWSCredentials(credentials: Credentials): AWSCredentials = {
    System.out.println("Retrieved AWS Session Token and Credentials for assuming role")
    new BasicSessionCredentials(credentials.getAccessKeyId,
      credentials.getSecretAccessKey,
      credentials.getSessionToken)
  }

  def assumeRole(roleArn: String): AssumeRoleResult = {
    System.out.println(s"Making a request to AWS STS with the roleArn: $roleArn to assume a role")
    val stsClient = AWSSecurityTokenServiceClientBuilder
      .standard
      .withRegion(AWS_REGION)
      .build

    val assumeRoleRequest = new AssumeRoleRequest
    assumeRoleRequest.setRoleArn(roleArn)
    stsClient.assumeRole(assumeRoleRequest)
  }

  override def getCredentials: AWSCredentials = {
    val roleArn = getRoleArn
    if (roleArn == null || roleArn == "") {
      System.out.println(s"Key of name $ROLE_ARN_KEY was not found in file at ${file.getAbsolutePath}")
      return null
    }
    System.out.println(s"$ROLE_ARN_KEY was read from ${file.getAbsolutePath} successfully")
    val assumeRoleResult = assumeRole(roleArn)
    System.out.println("Request to assume role using AWS STS successful")
    createAWSCredentials(assumeRoleResult.getCredentials)
  }

  override def refresh(): Unit = {}
}

object PropertyFilesCredentialProvider {

  private val DOT_SBT_DIR: File =
    new File(System.getProperty("user.home"), ".sbt")

  /** Uses a bucket specific propertyfile to read AWS `roleArn` from and provides it
    * to the PropertyFilesCredentialProvider.
    *
    * @param bucket Name of the S3 bucket.
    * @return a PropertyFileCredentialProvider
    */
  def create(bucket: String): PropertyFilesCredentialProvider = {
    val fileName = s".${bucket}_s3credentials"
    System.out.println("Using the Property Files Credential Provider")
    System.out.println(s"Reading $fileName for AWS Credentials ")
    val file: File = new File(DOT_SBT_DIR, fileName)
    new PropertyFilesCredentialProvider(file)
  }
}

ОБНОВЛЕНИЕ

Попытки использовать streams.value.log не удалось с ошибкой:

`value` can only be called on a task within a task definition macro, 
 such as :=, +=, ++=, or Def.task.
[error]   val logger = streams.value.log
[error]   

Попытки использовать ConsoleLogger, который является подклассом Logger, носоздан в классе.Метод apply был вызван так:

val logger = sbt.internal.util.ConsoleLogger(System.out)
logger.info("s"Key of name $ROLE_ARN_KEY was not found in file at ${file.getAbsolutePath}"")

внутри класса выше.Это также не выводило журналы.

Я создал два регистратора, один для класса и другой для объекта-компаньона в качестве членов, а не внутри класса, расширяющего AutoPlugin.

1 Ответ

0 голосов
/ 06 февраля 2019

Это способ добавления регистрации в классы, которые вы определили для вашего AutoPlugin

import sbt._
import sbt.Keys._

object TestPlugin extends AutoPlugin {

  class SomeClassThatNeedsLogger(logger: Logger) {
    def doSomeLogging(): Unit = {
      logger.info("It logs")
    }
  }

  object autoImport {
    val someClassThatNeedsLoggerHolder = taskKey[SomeClassThatNeedsLogger]("Holds instance of SomeClassThatNeedsLogger")
    val runSomeClassThatNeedsLogger = taskKey[Unit]("Runs SomeClassThatNeedsLogger")
  }

  import autoImport._

  override def trigger = allRequirements

  override def projectSettings: Seq[Def.Setting[_]] = {
    Seq(
      someClassThatNeedsLoggerHolder := new SomeClassThatNeedsLogger(streams.value.log),
      runSomeClassThatNeedsLogger := someClassThatNeedsLoggerHolder.value.doSomeLogging()
    )
  }
}

. И запуск дает нам запись в журнале:

> runSomeClassThatNeedsLogger
[info] It logs
[success] Total time: 0 s, completed Feb 6, 2019 9:47:15 AM

Некоторые примечания об ошибкахвы получаете

value можно вызвать только для задачи в макросе определения задачи,
, такой как: =, + =, ++ = или Def.task.

Это говорит о том, что streams.value может использоваться только в определениях задач, таких как someClassThatNeedsLoggerHolder := new SomeClassThatNeedsLogger(streams.value.log)

ConsoleLogger с использованием sbt.util.internal

Как следует из названия пакета, это внутренний пакет, который может быть изменен в следующих версиях sbt.Он не должен использоваться в определениях вашего плагина.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...