Permalink
Browse files

Smoke test for KMS

  • Loading branch information...
amrhassan committed Dec 14, 2017
1 parent 6100f67 commit 9a11c3d78a5ac7b6bb6ec8ff0abede26b0ab188f
View
@@ -1,3 +1,5 @@
language: scala
scala:
- 2.12.4
script:
- sbt "testOnly *Spec"
View
@@ -28,12 +28,12 @@ val scalatestVersion = "3.0.4"
val circeVersion = "0.9.0-M2"
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-client" % http4sVersion,
"org.http4s" %% "http4s-circe" % http4sVersion,
"org.http4s" %% "http4s-scala-xml" % http4sVersion,
"io.circe" %% "circe-core" % circeVersion,
"io.circe" %% "circe-generic" % circeVersion,
"org.scalatest" %% "scalatest" % scalatestVersion % Test,
"org.http4s" %% "http4s-client" % http4sVersion,
"org.http4s" %% "http4s-circe" % http4sVersion,
"org.http4s" %% "http4s-scala-xml" % http4sVersion,
"io.circe" %% "circe-core" % circeVersion,
"org.scalatest" %% "scalatest" % scalatestVersion % Test,
"org.http4s" %% "http4s-blaze-client" % http4sVersion % Test,
)
publishTo := Some(
@@ -0,0 +1,9 @@
package org.aws4s
import java.time.Instant
import io.circe.Decoder
object ExtraCirceDecoders {
implicit val instantDecoder: Decoder[Instant] =
Decoder[Long] map Instant.ofEpochSecond
}
@@ -1,8 +1,7 @@
package org.aws4s.kms
import cats.effect.Effect
import io.circe.generic.JsonCodec
import io.circe.Json
import io.circe.{Decoder, Json}
import org.aws4s.Param.RenderedOptional
import org.aws4s.Region
@@ -21,7 +20,11 @@ private [kms] object CreateKey {
case class DescriptionParam(value: String) extends KmsParam[String]("Description", d => if (d.length > 8192) Some("length not in [1,8192]") else None)
}
@JsonCodec(decodeOnly = true)
case class CreateKeySuccess(
keyMetadata: KeyMetadata,
)
object CreateKeySuccess {
implicit val decoder: Decoder[CreateKeySuccess] =
Decoder.forProduct1("KeyMetadata")(CreateKeySuccess.apply)
}
@@ -1,10 +1,14 @@
package org.aws4s.kms
import io.circe.generic.JsonCodec
import io.circe.Decoder
import org.aws4s.Arn
@JsonCodec(decodeOnly = true)
case class KeyMetadata(
arn: Arn,
keyId: KeyId,
)
object KeyMetadata {
implicit val decoder: Decoder[KeyMetadata] =
Decoder.forProduct2("Arn", "KeyId")(KeyMetadata.apply)
}
@@ -14,7 +14,7 @@ case class Kms[F[_]: Effect](client: Client[F], region: Region, credentials: ()
keyId: KeyId,
plaintext: Array[Byte],
context: Option[Map[String, String]] = None,
grantTokens: Option[GrantTokens],
grantTokens: Option[GrantTokens] = None,
): F[EncryptSuccess] = run {
Encrypt(
region,
@@ -27,8 +27,8 @@ case class Kms[F[_]: Effect](client: Client[F], region: Region, credentials: ()
def decrypt(
ciphertext: Array[Byte],
context: Option[Map[String, String]],
grantTokens: Option[GrantTokens],
context: Option[Map[String, String]] = None,
grantTokens: Option[GrantTokens] = None,
): F[DecryptSuccess] = run {
Decrypt(
region,
@@ -42,7 +42,7 @@ case class Kms[F[_]: Effect](client: Client[F], region: Region, credentials: ()
CreateKey(region, description map DescriptionParam.apply)
}
def scheduleKeyDeletion(keyId: KeyId, pendingWindowInDays: Option[Int] = None): F[Unit] = run {
def scheduleKeyDeletion(keyId: KeyId, pendingWindowInDays: Option[Int] = None): F[ScheduleKeyDeletionSuccess] = run {
ScheduleKeyDeletion(region, KeyIdParam(keyId), pendingWindowInDays map PendingWindowInDaysParam.apply)
}
}
@@ -1,16 +1,18 @@
package org.aws4s.kms
import java.time.Instant
import cats.effect.Effect
import io.circe.Json
import io.circe.{Decoder, Json}
import org.aws4s.Param.RenderedOptional
import org.aws4s.Region
import org.aws4s.kms.ScheduleKeyDeletion.PendingWindowInDaysParam
import org.aws4s.ExtraCirceDecoders._
private [kms] case class ScheduleKeyDeletion[F[_]: Effect](
region: Region,
keyId: KeyIdParam,
pendingWindowInDays: Option[PendingWindowInDaysParam],
) extends KmsCommand[F, Unit] {
) extends KmsCommand[F, ScheduleKeyDeletionSuccess] {
override def action: String = "ScheduleKeyDeletion"
override def params: List[RenderedOptional[Json]] =
List(
@@ -22,3 +24,16 @@ private [kms] case class ScheduleKeyDeletion[F[_]: Effect](
private [kms] object ScheduleKeyDeletion {
case class PendingWindowInDaysParam(value: Int) extends KmsParam[Int]("PendingWindowInDays", n => if (n < 7 || n > 30) Some("not in [7,30]") else None)
}
case class ScheduleKeyDeletionSuccess(
keyId: KeyId,
deletionDate: Instant,
)
object ScheduleKeyDeletionSuccess {
implicit val decoder: Decoder[ScheduleKeyDeletionSuccess] =
Decoder.forProduct2(
"KeyId",
"DeletionDate"
)(ScheduleKeyDeletionSuccess.apply)
}
@@ -0,0 +1,18 @@
package org.aws4s
import cats.effect.IO
import org.http4s.client.blaze.SimpleHttp1Client
import org.scalatest.{AsyncFlatSpec, Matchers}
abstract class SmokeTest extends AsyncFlatSpec with Matchers {
final val httpClient = SimpleHttp1Client[IO]()
final val region = Region.`eu-central-1`
final val credentials = () => Credentials(getEnvOrDie("AWS_ACCESS_KEY"), getEnvOrDie("AWS_SECRET_KEY"))
private final def getEnvOrDie(name: String): String =
Option(System.getenv(name)) match {
case Some(v) => v
case None => throw new RuntimeException(s"ENV variable $name is missing")
}
}
@@ -0,0 +1,22 @@
package org.aws4s.kms
import java.time.ZonedDateTime
import org.aws4s.SmokeTest
class KmsSmokeTest extends SmokeTest {
"Essential functionality" should "be alright" in {
val kms = Kms(httpClient, region, credentials)
val all = for {
keyId <- kms.createKey(Some(s"KMS smoke-test key ${ZonedDateTime.now}")) map (_.keyMetadata.keyId)
d = "secretdata"
ciphertext <- kms.encrypt(keyId, d.getBytes) map (_.cipherText)
plaintext <- kms.decrypt(ciphertext) map (_.plainText)
_ <- kms.scheduleKeyDeletion(keyId, Some(7))
} yield new String(plaintext) == d
all.unsafeToFuture() map (assert(_))
}
}

0 comments on commit 9a11c3d

Please sign in to comment.