Skip to content

Commit

Permalink
Merge pull request #121 from tylersouthwick/emr
Browse files Browse the repository at this point in the history
Add EMR support
  • Loading branch information
bkrodgers committed Nov 30, 2016
2 parents 0de1c10 + b03aa4a commit a09ed9b
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -135,6 +135,7 @@ describe("Template Lookup") {
- AWS::ElasticBeanstalk::ApplicationVersion
- AWS::ElasticBeanstalk::ConfigurationTemplate
- AWS::ElasticBeanstalk::Environment
- AWS::EMR::Cluster
- AWS::IAM::AccessKey
- AWS::IAM::Group
- AWS::IAM::InstanceProfile
Expand Down
@@ -0,0 +1,124 @@
package com.monsanto.arch.cloudformation.model.resource

import com.monsanto.arch.cloudformation.model.{ConditionRef, Token}
import spray.json.{DefaultJsonProtocol, JsObject, JsValue, JsonFormat, RootJsonFormat}
import DefaultJsonProtocol._


case class Application(
AdditionalInfo: Option[Map[String, Token[String]]],
Args: Option[Seq[Token[String]]],
Name: Option[Token[String]],
Version: Option[Token[String]]
)

object Application {
implicit val format = jsonFormat4(Application.apply)
}

case class ScriptBootstrapAction(Args: Option[Seq[Token[String]]], Path: Token[String])
object ScriptBootstrapAction {
implicit val format = jsonFormat2(ScriptBootstrapAction.apply)
}

case class BootstrapAction(Name: Token[String], ScriptBootstrapAction: ScriptBootstrapAction)
object BootstrapAction {
implicit val format = jsonFormat2(BootstrapAction.apply)
}

case class ClusterConfiguration(Classification: Option[Token[String]],
ConfigurationProperties: Option[Map[String, Token[String]]],
Configurations: Option[Seq[ClusterConfiguration]]
)
object ClusterConfiguration {
implicit object format extends RootJsonFormat[ClusterConfiguration] {
override def write(obj: ClusterConfiguration): JsValue = {
val classification = obj.Classification.map(implicitly[JsonFormat[Token[String]]].write)
val configurationProperties = obj.ConfigurationProperties.map(implicitly[JsonFormat[Map[String, Token[String]]]].write)
lazy val seqWrite = implicitly[RootJsonFormat[Seq[ClusterConfiguration]]]
val configurations = obj.Configurations.map(seqWrite.write)
JsObject(Seq(
"Classification" -> classification,
"ConfigurationProperties" -> configurationProperties,
"Configurations" -> configurations
).flatMap(t => t._2.map(t._1 -> _).toSeq)
.toMap)
}

override def read(json: JsValue): ClusterConfiguration = ???
}
}

case class VolumeSpecification(Iops: Option[Token[Int]], SizeInGB: Token[Int], VolumeType: Token[String])
object VolumeSpecification {
implicit val format = jsonFormat3(VolumeSpecification.apply)
}

case class EbsBlockDeviceConfig(VolumeSpecification: VolumeSpecification, VolumesPerInstance: Option[Token[Int]])
object EbsBlockDeviceConfig {
implicit val format = jsonFormat2(EbsBlockDeviceConfig.apply)
}

case class EbsConfiguration(EbsBlockDeviceConfigs: Option[Seq[EbsBlockDeviceConfig]],
EbsOptimized: Option[Token[Boolean]])
object EbsConfiguration {
implicit val format = jsonFormat2(EbsConfiguration.apply)
}

case class InstanceGroupConfig(
BidPrice: Option[Token[String]],
Configurations: Option[Seq[ClusterConfiguration]],
EbsConfiguration: Option[EbsConfiguration],
InstanceCount: Token[Int],
InstanceType: Token[String],
Market: Option[Token[String]],
Name: Option[Token[String]]
)
object InstanceGroupConfig {
implicit val format = jsonFormat7(InstanceGroupConfig.apply)
}

case class PlacementType(AvailabilityZone: String)
object PlacementType {
implicit val format = jsonFormat1(PlacementType.apply)
}

case class JobFlowInstancesConfig(AdditionalMasterSecurityGroups: Option[Seq[Token[String]]],
AdditionalSlaveSecurityGroups: Option[Seq[Token[String]]],
CoreInstanceGroup: InstanceGroupConfig,
Ec2KeyName: Option[Token[String]],
Ec2SubnetId: Option[Token[String]],
EmrManagedMasterSecurityGroup: Option[Token[String]],
EmrManagedSlaveSecurityGroup: Option[Token[String]],
HadoopVersion: Option[Token[String]],
MasterInstanceGroup: InstanceGroupConfig,
Placement: Option[PlacementType],
ServiceAccessSecurityGroup: Option[Token[String]],
TerminationProtected: Option[Token[Boolean]]
)
object JobFlowInstancesConfig {
implicit val format = jsonFormat12(JobFlowInstancesConfig.apply)
}

case class `AWS::EMR::Cluster`(name: String,
AdditionalInfo: Option[JsValue],
Applications: Option[Seq[Application]],
BootstrapActions: Option[Seq[BootstrapAction]],
Configurations: Option[Seq[ClusterConfiguration]],
Instances: JobFlowInstancesConfig,
JobFlowRole: Token[String],
LogUri: Option[Token[String]],
Name: Token[String],
ReleaseLabel: Option[Token[String]],
ServiceRole: Token[String],
Tags: Option[Seq[AmazonTag]],
VisibileToAllUsers: Option[Token[Boolean]],
override val Condition: Option[ConditionRef] = None
) extends Resource[`AWS::EMR::Cluster`] {
override def when(newCondition: Option[ConditionRef]): `AWS::EMR::Cluster` = copy(
Condition = newCondition
)
}
object `AWS::EMR::Cluster` {
implicit val format : JsonFormat[`AWS::EMR::Cluster`] = jsonFormat14(`AWS::EMR::Cluster`.apply)
}
@@ -0,0 +1,54 @@
package com.monsanto.arch.cloudformation.model.resource

import org.scalatest.{FunSpec, Matchers}
import spray.json.{JsArray, JsObject, JsString, JsonWriter}

class EmrSpec extends FunSpec with Matchers {

describe("ClusterConfiguration") {
it("should write non recursive") {
val clusterConfiguration = ClusterConfiguration(
Classification = Some("hello"),
ConfigurationProperties = Some(Map("hello" -> "world")),
Configurations = None
)
val json = implicitly[JsonWriter[ClusterConfiguration]].write(clusterConfiguration)
json should equal(JsObject(Map(
"Classification" -> JsString("hello"),
"ConfigurationProperties" -> JsObject(
"hello" -> JsString("world")
)
)))
}

it("should write and read recursive") {
val clusterConfiguration = ClusterConfiguration(
Classification = Some("hello"),
ConfigurationProperties = Some(Map("hello" -> "world")),
Configurations = Some(Seq(
ClusterConfiguration(
Classification = Some("hello1"),
ConfigurationProperties = Some(Map("hello2" -> "world3")),
Configurations = None
)
))
)
val json = implicitly[JsonWriter[ClusterConfiguration]].write(clusterConfiguration)
json should equal(JsObject(Map(
"Classification" -> JsString("hello"),
"ConfigurationProperties" -> JsObject(
"hello" -> JsString("world")
),
"Configurations" -> JsArray(
JsObject(Map(
"Classification" -> JsString("hello1"),
"ConfigurationProperties" -> JsObject(
"hello2" -> JsString("world3")
)
))
)
)))
}
}

}

0 comments on commit a09ed9b

Please sign in to comment.