Модульный тест или интеграционный тест для загрузки конфигурации из секрета kubernetes с использованием ciris-kubernetes - PullRequest
2 голосов
/ 26 марта 2019

Привет сообщество scala,

Я использую ciris-kubernetes для ввода учетных данных и сертификатов из секретов kubernetes. Хоть это и работает как шарм, мне интересно, как лучше всего было бы провести модульное тестирование или написать интеграционный тест для этой функции?

В частности, если одной из основных задач конфигурации как кода является написание тестов для него, разве этому аспекту не следует придавать большее значение?

Вот мой класс дел для хранения конфигурации

import java.io.File 
import ciris.Secret 

final case class SAMLCertificateConfiguration(publicKey: Secret[File], privateKey: Secret[File], password: Secret[String])

и загрузчик конфигурации

object ConfigurationLoader {

  private[this] val log = LoggerFactory getLogger this.getClass

  private def createConfigurationUsingSecret(namespace: NonEmptyString, secretName: NonEmptyString): IO[SAMLCertificateConfiguration] = {

    def getKubernetesSecret: IO[SecretInNamespace[IO]] =
      for {
        apiClient <- defaultApiClient[IO]
      } yield secretInNamespace[IO](namespace, apiClient)

    def createCertificateConfigurationWith(secret: SecretInNamespace[IO]): IO[SAMLCertificateConfiguration] =
      loadConfig(secret[Secret[File]](secretName.value, "public.crt"), secret[Secret[File]](secretName.value, "private.pfx"), secret[Secret[String]](secretName.value, "password")) {
        (publicKey, privateKey, privateKeyPassword) =>
          SAMLCertificateConfiguration(publicKey, privateKey, privateKeyPassword)
      }.orRaiseThrowable

    for {
      secret <- getKubernetesSecret
      samlCertificateConfiguration <- createCertificateConfigurationWith(secret)
    } yield samlCertificateConfiguration

  }

  def loadSAMLCertificateConfiguration: IO[SAMLCertificateConfiguration] =
    loadConfig(
      envF[IO, ApplicationEnvironment]("APPLICATION_ENVIRONMENT")
        .orElse(propF[IO, ApplicationEnvironment]("application.environment"))
        .orNone,
      envF[IO, NonEmptyString]("KUBERNETES_NAMESPACE")
        .orElse(propF[IO, NonEmptyString]("kubernetes.namespace"))
        .orValue("default"),
      envF[IO, NonEmptyString]("KUBERNETES_SECRET_NAME")
        .orElse(propF[IO, NonEmptyString]("kubernetes.secret.name"))
        .orValue("saml-pfx")
    ) { (environment, namespace, secret) =>
      import pp.util.configuration.ApplicationEnvironment._
      log.info(s"Environment: $environment, Kubernetes namespace: $namespace, Kubernetes secret's name: $secret")
      environment match {
        case Some(Test) | Some(Production) =>
          createConfigurationUsingSecret(namespace, secret).unsafeRunSync()
        case _ =>
          createSAMLCertificateConfigurationUsingHOCON
      }
    }.orRaiseThrowable

}

import enumeratum.{Enum, EnumEntry}
import scala.collection.immutable

sealed abstract class ApplicationEnvironment extends EnumEntry

object ApplicationEnvironment extends Enum[ApplicationEnvironment] {
  case object Development extends ApplicationEnvironment
  case object Test extends ApplicationEnvironment
  case object Production extends ApplicationEnvironment
  def values: immutable.IndexedSeq[ApplicationEnvironment] = findValues
}

import ciris._
import lt.dvim.ciris.Hocon._
import com.typesafe.config.ConfigFactory

object DefaultConfigurationLoader {

  def createSAMLCertificateConfigurationUsingHOCON: SAMLCertificateConfiguration = {

    def defaultConfiguration = {
      val fallbackConfiguration = ConfigFactory.parseString("""
                    |saml.certificate {
                    |  privateKey = "/tmp/certificates/private.pfx"
                    |  publicKey = "/tmp/certificates/public.crt"
                    |  password = ""
                    |}
                """.stripMargin)
      ConfigFactory.load().withFallback(fallbackConfiguration)
    }

    def hocon = hoconAt(defaultConfiguration)("saml.certificate")

    loadConfig(hocon[String]("publicKey"), hocon[String]("privateKey"), hocon[String]("password"))((publicKeyPath, privateKeyPath, privateKeyPassword) => {
      import java.nio.file.Paths
      import ciris.Secret
      SAMLCertificateConfiguration(Secret(Paths.get(publicKeyPath).toFile), Secret(Paths.get(privateKeyPath).toFile), Secret(privateKeyPassword))
    }).orThrow()
  }

}

Следует ли использовать io.fabric8.kubernetes.client.server.mock.KubernetesServer , как показано здесь , и неявно внедрить Java-клиент kubernetes в конфигурацию загрузчик, чтобы его можно было проверять в тестах?

...