Привет сообщество 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 в конфигурацию загрузчик, чтобы его можно было проверять в тестах?