package com.goyeau.kubernetes.client.operation import cats.Applicative import cats.implicits._ import com.goyeau.kubernetes.client.KubernetesClient import com.goyeau.kubernetes.client.Utils.retry import io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta import org.http4s.Status import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatest.{Assertion, OptionValues} trait CreatableTests[F[_], Resource <: { def metadata: Option[ObjectMeta] }] extends AnyFlatSpec with Matchers with OptionValues with MinikubeClientProvider[F] { def namespacedApi(namespaceName: String)(implicit client: KubernetesClient[F]): Creatable[F, Resource] def getChecked(namespaceName: String, resourceName: String)(implicit client: KubernetesClient[F]): F[Resource] def sampleResource(resourceName: String, labels: Map[String, String] = Map.empty): Resource def modifyResource(resource: Resource): Resource def checkUpdated(updatedResource: Resource): Assertion def createChecked(namespaceName: String, resourceName: String)( implicit client: KubernetesClient[F] ): F[Resource] = createChecked(namespaceName, resourceName, Map.empty) def createChecked(namespaceName: String, resourceName: String, labels: Map[String, String])( implicit client: KubernetesClient[F] ): F[Resource] = { val resource = sampleResource(resourceName, labels) for { status <- namespacedApi(namespaceName).create(resource) _ = status shouldBe Status.Created resource <- getChecked(namespaceName, resourceName) } yield resource } "create" should s"create a $resourceName" in usingMinikube { implicit client => createChecked(resourceName.toLowerCase, "create-resource") } "createOrUpdate" should s"create a $resourceName" in usingMinikube { implicit client => for { namespaceName <- Applicative[F].pure(resourceName.toLowerCase) resourceName = "create-update-resource" status <- namespacedApi(namespaceName).createOrUpdate(sampleResource(resourceName)) _ = status shouldBe Status.Created _ <- getChecked(namespaceName, resourceName) } yield () } def createOrUpdate(namespaceName: String, resourceName: String)(implicit client: KubernetesClient[F]) = for { resource <- getChecked(namespaceName, resourceName) status <- namespacedApi(namespaceName).createOrUpdate(modifyResource(resource)) _ = status shouldBe Status.Ok } yield () it should s"update a $resourceName already created" in usingMinikube { implicit client => for { namespaceName <- Applicative[F].pure(resourceName.toLowerCase) resourceName <- Applicative[F].pure("update-resource") _ <- createChecked(namespaceName, resourceName) _ <- retry(createOrUpdate(namespaceName, resourceName)) updatedResource <- getChecked(namespaceName, resourceName) _ = checkUpdated(updatedResource) } yield () } }