Skip to content

Commit

Permalink
Adds AWS::EC2::CustomerGateway support
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Fokken committed Jan 19, 2016
1 parent aa4845f commit ec247f6
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe("Template Lookup") {
- AWS::AutoScaling::ScalingPolicy
- AWS::CloudWatch::Alarm
- AWS::DynamoDB::Table
- AWS::EC2::CustomerGateway
- AWS::EC2::EIP
- AWS::EC2::Instance
- AWS::EC2::InternetGateway
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.monsanto.arch.cloudformation.model

import spray.json._

import scala.collection.immutable.ListMap

/**
* Created by bkrodg on 2/16/15.
*/
Expand All @@ -12,6 +14,6 @@ object Condition extends DefaultJsonProtocol {
def write(obj: Condition) = obj.function.toJson
}

def write(objs: Seq[Condition]) = JsObject( objs.map( o => o.name -> o.toJson ).toMap )
def write(objs: Seq[Condition]) = JsObject( ListMap(objs.map( o => o.name -> o.toJson ): _*) )
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.monsanto.arch.cloudformation.model
import spray.json._
import DefaultJsonProtocol._

import scala.collection.immutable.ListMap

/**
* Created by Ryan Richt on 2/15/15
*/
Expand All @@ -25,6 +27,6 @@ object Mapping extends DefaultJsonProtocol {
}
}

def write(objs: Seq[Mapping[_]]) = JsObject(objs.map(o => o.name -> format.write(o)).toMap)
def write(objs: Seq[Mapping[_]]) = JsObject(ListMap(objs.map(o => o.name -> format.write(o)): _*))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.monsanto.arch.cloudformation.model
import spray.json._
import DefaultJsonProtocol._

import scala.collection.immutable.ListMap

/**
* Created by Ryan Richt on 2/15/15
*/
Expand All @@ -21,6 +23,6 @@ object Output extends DefaultJsonProtocol {
)
}

def write(objs: Seq[Output[_]]) = JsObject(objs.map(o => o.name -> format.write(o)).toMap)
def write(objs: Seq[Output[_]]) = JsObject(ListMap(objs.map(o => o.name -> format.write(o)): _*))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.monsanto.arch.cloudformation.model
import com.monsanto.arch.cloudformation.model.resource._
import spray.json._
import DefaultJsonProtocol._
import scala.collection.immutable.ListMap
import scala.language.implicitConversions

/**
Expand Down Expand Up @@ -38,7 +39,7 @@ object Parameter extends DefaultJsonProtocol {
}
}

def write(objs: Seq[Parameter]) = JsObject( objs.map( o => o.name -> o.toJson ).toMap )
def write(objs: Seq[Parameter]) = JsObject( ListMap(objs.map( o => o.name -> o.toJson ): _*) )
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.monsanto.arch.cloudformation.model.simple.SecurityGroupRoutable
import spray.json._
import DefaultJsonProtocol._

import scala.collection.immutable.ListMap
import scala.language.implicitConversions
import scala.reflect.ClassTag

Expand Down Expand Up @@ -114,7 +115,7 @@ object Template extends DefaultJsonProtocol {
if(p.Mappings.nonEmpty) fields ++= productElement2Field[Option[Seq[Mapping[_]]]]("Mappings", p, 3)
if(p.Resources.nonEmpty) fields ++= productElement2Field[Option[Seq[Resource[_]]]]("Resources", p, 4)
if(p.Outputs.nonEmpty) fields ++= productElement2Field[Option[Seq[Output[_]]]]("Outputs", p, 6)
JsObject(fields: _*)
JsObject(ListMap(fields: _*))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,25 @@ case class `AWS::EC2::EIP`(
) extends Resource[`AWS::EC2::EIP`]{
def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}

object `AWS::EC2::EIP` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::EC2::EIP`] = jsonFormat5(`AWS::EC2::EIP`.apply)
}

case class `AWS::EC2::EIPAssociation`(
name: String,
AllocationId: Option[Token[String]],
InstanceId: Token[ResourceRef[`AWS::EC2::Instance`]],
override val Condition: Option[ConditionRef] = None,
override val DependsOn: Option[Seq[String]] = None
) extends Resource[`AWS::EC2::EIPAssociation`]{
def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}

object `AWS::EC2::EIPAssociation` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::EC2::EIPAssociation`] = jsonFormat5(`AWS::EC2::EIPAssociation`.apply)
}

case class AMIId(id: String)
object AMIId extends DefaultJsonProtocol {
implicit val format: JsonFormat[AMIId] = new JsonFormat[AMIId] {
Expand Down Expand Up @@ -78,6 +93,20 @@ object `AWS::EC2::KeyPair::KeyName` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::EC2::KeyPair::KeyName`] = jsonFormat2(`AWS::EC2::KeyPair::KeyName`.apply)
}

case class `AWS::EC2::CustomerGateway`(
name: String,
BgpAsn: Int,
IpAddress: IPAddress,
Tags: Seq[AmazonTag],
Type: String,
override val Condition: Option[ConditionRef] = None) extends Resource[`AWS::EC2::CustomerGateway`]{

def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}
object `AWS::EC2::CustomerGateway` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::EC2::CustomerGateway`] = jsonFormat6(`AWS::EC2::CustomerGateway`.apply)
}

@implicitNotFound("A Route can only have exactly ONE of GatewayId, InstanceId, NetworkInterfaceId or VpcPeeringConnectionId set")
class ValidRouteCombo[G, I] private ()
object ValidRouteCombo{
Expand Down Expand Up @@ -217,6 +246,21 @@ object CidrBlock extends DefaultJsonProtocol {
}
}

case class IPAddress(a: IPAddressSegment, b: IPAddressSegment, c: IPAddressSegment, d: IPAddressSegment) {
def toJsString: JsString = JsString( Seq(a, b, c, d).map(_.value.toString).mkString("."))
}
object IPAddress extends DefaultJsonProtocol {
implicit val format: JsonFormat[IPAddress] = new JsonFormat[IPAddress] {
def write(obj: IPAddress) = obj.toJsString

def read(json: JsValue) = {
val parts = json.convertTo[String].split(Array('.')).map(_.toInt)

IPAddress(parts(0), parts(1), parts(2), parts(3))
}
}
}

sealed trait EgressSpec
object EgressSpec extends DefaultJsonProtocol {
implicit val format: JsonFormat[EgressSpec] = new JsonFormat[EgressSpec] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ package com.monsanto.arch.cloudformation.model.resource
import com.monsanto.arch.cloudformation.model._
import spray.json._

import scala.collection.immutable.ListMap
import scala.language.implicitConversions
import scala.reflect.ClassTag
import scala.reflect.NameTransformer


/**
* Created by Ryan Richt on 2/15/15
*/

// serializes to Type and Properties
abstract class Resource[R <: Resource[R] : ClassTag : JsonFormat]{ self: Resource[R] =>
val Type = NameTransformer.decode(implicitly[ClassTag[R]].runtimeClass.getSimpleName)
val ResourceType = NameTransformer.decode(implicitly[ClassTag[R]].runtimeClass.getSimpleName)
val name: String

val Condition: Option[ConditionRef] = None
Expand All @@ -35,7 +37,7 @@ object Resource extends DefaultJsonProtocol {
val raw = bar._format.asInstanceOf[JsonFormat[obj.RR]].write(bar).asJsObject

val outputFields = Map(
"Type" -> JsString(obj.Type),
"Type" -> JsString(obj.ResourceType),
"Metadata" -> raw.fields.getOrElse("Metadata", JsNull),
"Properties" -> JsObject(raw.fields - "name" - "Metadata" - "UpdatePolicy" - "Condition" - "DependsOn" - "DeletionPolicy"),
"UpdatePolicy" -> raw.fields.getOrElse("UpdatePolicy", JsNull),
Expand All @@ -48,7 +50,7 @@ object Resource extends DefaultJsonProtocol {
}
}

def write(objs: Seq[Resource[_]]) = JsObject( objs.map( o => o.name -> format.write(o) ).toMap )
def write(objs: Seq[Resource[_]]) = JsObject( ListMap(objs.map( o => o.name -> format.write(o) ): _*) )
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.monsanto.arch.cloudformation.model.resource

import com.monsanto.arch.cloudformation.model._
import org.scalatest.{FunSpec, Matchers}
import spray.json._

class CGW_UT extends FunSpec with Matchers {
describe("AWS::EC2::CustomerGateway") {
val bpgAsn = 1234
val ipAddr = IPAddress(8, 8, 8, 8)
val cgwType = "ipsec.1"
val cgw = `AWS::EC2::CustomerGateway`(
name = "cgw",
BgpAsn = 1234,
IpAddress = ipAddr,
Tags = Seq(),
Type = "ipsec.1"
)
it("should create a valid new Customer Gateway") {
val expected = JsObject(
"cgw" -> JsObject(
"Type" -> JsString("AWS::EC2::CustomerGateway"),
"Properties" -> JsObject(
"BgpAsn" -> JsNumber(bpgAsn),
"IpAddress" -> ipAddr.toJsString,
"Tags" -> JsArray(),
"Type" -> JsString(cgwType)
)
)
)
Seq[Resource[_]](cgw).toJson should be(expected)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.monsanto.arch.cloudformation.model.resource

import org.scalatest.{Matchers, FunSpec}
import spray.json._

class EC2_UT extends FunSpec with Matchers {

describe("CidrBlock"){

val cidr = CidrBlock(192,168,1,2,32)

it("should write valid CidrBlock"){
cidr.toJson shouldEqual JsString("192.168.1.2/32")
}

it("should read valid CidrBlock") {
JsString("192.168.1.2/32").convertTo[CidrBlock] shouldEqual cidr
}

}

describe("IPAddress"){
val ipAddress = IPAddress(192,168,1,2)

it("should write valid IPAddress"){
ipAddress.toJson shouldEqual JsString("192.168.1.2")
}

it("should read valid IPAddress"){
JsString("192.168.1.2").convertTo[IPAddress] shouldEqual ipAddress
}

}
}

0 comments on commit ec247f6

Please sign in to comment.