Skip to content

Commit

Permalink
Added resources and changed a parameter or two. (#111)
Browse files Browse the repository at this point in the history
* Add MariaDB RDS engine type.
Change RDS dbports to be tokens, this allows us to set them via parameters.

* Performing updates to local generator branch. Updating monitoring and game stacks.

* Added elasticache. Added SubnetNetworkAclAssociation for EC2. Changed Beanstalk environment to take an `Option[ResourceRef[`AWS::ElasticBeanstalk::ConfigurationTemplate`]]` for its comfiguration template parameter.

* Added new resources to README.md

* Added AWS::ECR::Repository to README.md

* Added unit tests to improve coverage.
  • Loading branch information
elyzion authored and T.J. Corrigan committed Nov 4, 2016
1 parent 4a0658c commit 8dec124
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 5 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ describe("Template Lookup") {
- AWS::EC2::SecurityGroupEgress
- AWS::EC2::SecurityGroupIngress
- AWS::EC2::Subnet
- AWS::EC2::SubnetNetworkAclAssociation
- AWS::EC2::SubnetRouteTableAssociation
- AWS::EC2::VPC
- AWS::EC2::VPCGatewayAttachment
Expand All @@ -125,6 +126,9 @@ describe("Template Lookup") {
- AWS::EC2::VPNGateway
- AWS::EC2::Volume
- AWS::EC2::VolumeAttachment
- AWS::ECR::Repository
- AWS::ElastiCache::CacheCluser
- AWS::ElastiCache::SubnetGroup
- AWS::Elasticsearch::Domain
- AWS::ElasticLoadBalancing::LoadBalancer
- AWS::ElasticBeanstalk::Application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,19 @@ object `AWS::EC2::SubnetRouteTableAssociation` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::EC2::SubnetRouteTableAssociation`] = jsonFormat4(`AWS::EC2::SubnetRouteTableAssociation`.apply)
}

case class `AWS::EC2::SubnetNetworkAclAssociation`(
name: String,
SubnetId: Token[ResourceRef[`AWS::EC2::Subnet`]],
NetworkAclId: Token[ResourceRef[`AWS::EC2::NetworkAcl`]],
override val Condition: Option[ConditionRef] = None
) extends Resource[`AWS::EC2::SubnetNetworkAclAssociation`]{

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

case class `AWS::EC2::VPC`(name: String, CidrBlock: Token[CidrBlock], Tags: Seq[AmazonTag], EnableDnsSupport: Boolean = true, EnableDnsHostnames: Boolean = false,
override val Condition: Option[ConditionRef] = None) extends Resource[`AWS::EC2::VPC`]{

Expand Down Expand Up @@ -629,6 +642,9 @@ object `AWS::EC2::Volume` extends DefaultJsonProtocol {
def io2(name: String, az: Token[String], size: Token[Int], tags: Seq[AmazonTag], iops: Int, encrypted: Boolean = true ) =
`AWS::EC2::Volume`(name, az, Some(encrypted), None, Some(size), None, tags, "io2")

def io1(name: String, az: Token[String], size: Token[Int], tags: Seq[AmazonTag], iops: Int, encrypted: Boolean = true ) =
`AWS::EC2::Volume`(name, az, Some(encrypted), Some(iops), Some(size), None, tags, "io1")

//require( size >= 1 && size <= 1024 )
def standard(name: String, az: Token[String], size: Token[Int], tags: Seq[AmazonTag], encrypted: Boolean = true ) =
`AWS::EC2::Volume`(name, az, Some(encrypted), None, Some(size), None, tags, "standard")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.monsanto.arch.cloudformation.model.resource

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

/**
* Created by Berthold Alheit on 13/09/16.
*/
case class `AWS::ECR::Repository`(
name: String,
RepositoryName: Option[Token[String]],
RepositoryPolicyText: Option[Token[PolicyDocument]] = None,
override val Condition: Option[ConditionRef] = None)
extends Resource[`AWS::ECR::Repository`] {
def when(newCondition: Option[ConditionRef] = Condition) =
new `AWS::ECR::Repository`(name, RepositoryName, RepositoryPolicyText, newCondition)
}
object `AWS::ECR::Repository` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::ECR::Repository`] = jsonFormat4(`AWS::ECR::Repository`.apply)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.monsanto.arch.cloudformation.model.resource

import com.monsanto.arch.cloudformation.model.{ConditionRef, ResourceRef, Token}
import spray.json.{DefaultJsonProtocol, JsonFormat}

/**
* Cache security group.
*
* @param name
* @param Description
* @param SubnetIds
* @param Condition
*/
case class `AWS::ElastiCache::SubnetGroup`(
name: String,
Description: String,
SubnetIds: Token[Seq[ResourceRef[`AWS::EC2::Subnet`]]],
override val Condition: Option[ConditionRef] = None
) extends Resource[`AWS::ElastiCache::SubnetGroup`]{

def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}

/**
* Json format definition for subnet group.
*/
object `AWS::ElastiCache::SubnetGroup` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::ElastiCache::SubnetGroup`] = jsonFormat4(`AWS::ElastiCache::SubnetGroup`.apply)
}

/**
* Cache cluster definition.
*
* @param name
* @param ClusterName
* @param CacheNodeType
* @param CacheSubnetGroupName
* @param VpcSecurityGroupIds
* @param Engine
* @param NumCacheNodes
* @param Tags
* @param Condition
*/
case class `AWS::ElastiCache::CacheCluster`(
name: String,
ClusterName: String,
CacheNodeType: String,
CacheSubnetGroupName: Token[ResourceRef[`AWS::ElastiCache::SubnetGroup`]],
VpcSecurityGroupIds: Option[Seq[Token[String]]],
Engine: String,
NumCacheNodes: Token[String],
Tags: Option[Seq[AmazonTag]] = None,
override val Condition: Option[ConditionRef] = None
) extends Resource[`AWS::ElastiCache::CacheCluster`]{

def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}

/**
* Json format definition for cache cluster
*/
object `AWS::ElastiCache::CacheCluster` extends DefaultJsonProtocol {
implicit val format: JsonFormat[`AWS::ElastiCache::CacheCluster`] = jsonFormat9(`AWS::ElastiCache::CacheCluster`.apply)
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ case class `AWS::ElasticBeanstalk::Environment`(
OptionSettings: Option[Seq[OptionSetting]] = None,
SolutionStackName: Option[String] = None,
Tags: Option[Seq[ResourceTag]] = None,
TemplateName: Option[String] = None,
TemplateName: Option[ResourceRef[`AWS::ElasticBeanstalk::ConfigurationTemplate`]] = None,
Tier: Option[EnvironmentTier] = None,
VersionLabel: Option[String] = None,
override val Condition: Option[ConditionRef] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ case class `AWS::RDS::DBInstance` private[resource] (
MasterUserPassword: Option[Token[String]],
MultiAZ: Option[Boolean],
OptionGroupName: Option[String],
Port: Option[String],
Port: Option[Token[String]],
PreferredBackupWindow: Option[String],
PreferredMaintenanceWindow: Option[String],
PubliclyAccessible: Option[Boolean],
Expand Down Expand Up @@ -444,7 +444,7 @@ object RdsBuilder {
engineVersion: Option[String] = None,
licenseModel: Option[`AWS::RDS::DBInstance::LicenseModel`] = None,
optionGroupName: Option[String] = None,
port: Option[String] = None,
port: Option[Token[String]] = None,
preferredMaintenanceWindow: Option[String] = None,
publiclyAccessible: Option[Boolean] = None,
tags: Option[Seq[AmazonTag]] = None,
Expand Down Expand Up @@ -505,7 +505,8 @@ sealed trait `AWS::RDS::DBInstance::Engine`
object `AWS::RDS::DBInstance::Engine` extends DefaultJsonProtocol {
case object MySQL extends `AWS::RDS::DBInstance::Engine`
case object postgres extends `AWS::RDS::DBInstance::Engine`
val values = Seq(MySQL, postgres)
case object MariaDB extends `AWS::RDS::DBInstance::Engine`
val values = Seq(MySQL, postgres, MariaDB)
implicit val format: JsonFormat[`AWS::RDS::DBInstance::Engine`] =
new EnumFormat[`AWS::RDS::DBInstance::Engine`](values)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.monsanto.arch.cloudformation.model.resource

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

class EC2_UT extends FunSpec with Matchers {

Expand Down Expand Up @@ -185,6 +185,47 @@ class EC2_UT extends FunSpec with Matchers {
}
}

describe("AWS::EC2::SubnetNetworkAclAssociation") {
val vpc = `AWS::EC2::VPC`(name = "vpc", CidrBlock(1, 1, 1, 1, 16), Seq())

val nAclName = "nACL"
val nAcl = `AWS::EC2::NetworkAcl`(
nAclName,
vpc,
Seq()
)

val subnetName = "subnet1a"
val subnet = `AWS::EC2::Subnet`(
name = subnetName,
AvailabilityZone = Some("ap-northeast-1a"),
VpcId = vpc,
CidrBlock = CidrBlock(1, 1, 1, 1, 24),
MapPublicIpOnLaunch = Some(true),
Tags = Seq()
)

val subnetNAclAssocName = "subnetNAclAssoc"
val subnetNAclAssoc = `AWS::EC2::SubnetNetworkAclAssociation`(
subnetNAclAssocName,
ResourceRef(subnet),
ResourceRef(nAcl)
)

it("should write a valid subnet network acl association entry") {
val expected = JsObject(
subnetNAclAssocName -> JsObject(
"Type" -> JsString("AWS::EC2::SubnetNetworkAclAssociation"),
"Properties" -> JsObject(
"SubnetId" -> JsObject("Ref" -> JsString(subnetName)),
"NetworkAclId" -> JsObject("Ref" -> JsString(nAclName))
)
)
)
Seq[Resource[_]](subnetNAclAssoc).toJson should be(expected)
}
}

describe("AWS::EC2::SecurityGroupIngress") {
val securityGroupParam = `AWS::EC2::SecurityGroup_Parameter`("testSGParam", "testSGParam")
val ingres = `AWS::EC2::SecurityGroupIngress`(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.monsanto.arch.cloudformation.model.resource

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

class ECR_UT extends FunSpec with Matchers {
describe("AWS::ECR::Repository") {

val fakePolicyDoc = PolicyDocument(Seq(
PolicyStatement(
"Allow",
Some(DefinedPrincipal(Map("Service" -> Seq("fakePrincipal")))),
Seq("fakeAction")
)
))

val repositoryName = "repository"
val repository = `AWS::ECR::Repository`(
repositoryName,
Some("myFakeDockerRepository"),
Some(fakePolicyDoc)
)

it("should create a valid new ECR repository") {
val expected = JsObject(
repositoryName -> JsObject(
"Type" -> JsString("AWS::ECR::Repository"),
"Properties" -> JsObject(
"RepositoryName" -> JsString("myFakeDockerRepository"),
"RepositoryPolicyText" -> fakePolicyDoc.toJson
)))
Seq[Resource[_]](repository).toJson should be(expected)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.monsanto.arch.cloudformation.model.resource

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

class ElastiCache_UT extends FunSpec with Matchers {
describe("AWS::ElastiCache::SubnetGroup") {
val vpc = `AWS::EC2::VPC`(
name = "VPC",
CidrBlock = CidrBlock(10, 10, 10, 10, 16),
Tags = Seq()
)
val subnetName = "subnet"
val subnet = `AWS::EC2::Subnet`(
name = subnetName,
VpcId = ResourceRef(vpc),
AvailabilityZone = Some("us-east-1a"),
CidrBlock = CidrBlock(10, 10, 10, 10, 24),
Tags = Seq()
)
val cacheSubnetGroupName = "cacheSubnetGroup"
val cacheSubnetGroup = `AWS::ElastiCache::SubnetGroup`(
name = cacheSubnetGroupName,
Description = "Not a real group",
SubnetIds = Seq(ResourceRef(subnet))
)

it("should create a valid new ElastiCache subnet group") {
val expected = JsObject(
cacheSubnetGroupName -> JsObject(
"Type" -> JsString("AWS::ElastiCache::SubnetGroup"),
"Properties" -> JsObject(
"Description" -> JsString("Not a real group"),
"SubnetIds" -> JsArray(JsObject("Ref" -> JsString(subnetName)))
)))
Seq[Resource[_]](cacheSubnetGroup).toJson should be(expected)
}
}

describe("AWS::ElastiCache::CacheCluster") {
val vpc = `AWS::EC2::VPC`(
name = "VPC",
CidrBlock = CidrBlock(10, 10, 10, 10, 16),
Tags = Seq()
)
val subnetName = "subnet"
val subnet = `AWS::EC2::Subnet`(
name = subnetName,
VpcId = ResourceRef(vpc),
AvailabilityZone = Some("us-east-1a"),
CidrBlock = CidrBlock(10, 10, 10, 10, 24),
Tags = Seq()
)
val cacheSubnetGroupName = "cacheSubnetGroup"
val cacheSubnetGroup = `AWS::ElastiCache::SubnetGroup`(
name = cacheSubnetGroupName,
Description = "Not a real group",
SubnetIds = Seq(ResourceRef(subnet))
)

val cacheSgName = "cacheSecurityGroup"
val cacheSg = `AWS::EC2::SecurityGroup`(
name = cacheSgName,
VpcId = vpc,
GroupDescription = s"Not a real security group",
SecurityGroupIngress = None,
Tags = Seq()
)

val cacheName = "cache"
val cache = `AWS::ElastiCache::CacheCluster`(
name = cacheName,
ClusterName = "fakeCluster",
CacheNodeType = "cache.t1.micro",
CacheSubnetGroupName = cacheSubnetGroup,
VpcSecurityGroupIds = Some(
Seq(`Fn::Join`("", Seq(`Fn::GetAtt`(Seq(cacheSg.name, "GroupId")))))
),
Engine = "redis",
NumCacheNodes = "1"
)

it("should create a valid new ElastiCache instance") {
val expected = JsObject(
cacheName -> JsObject(
"Type" -> JsString("AWS::ElastiCache::CacheCluster"),
"Properties" -> JsObject(
"ClusterName" -> JsString("fakeCluster"),
"CacheNodeType" -> JsString("cache.t1.micro"),
"CacheSubnetGroupName" -> JsObject("Ref" -> JsString(cacheSubnetGroupName)),
"VpcSecurityGroupIds" -> JsArray(
JsObject("Fn::Join" ->
JsArray(
JsString(""),
JsArray(
JsObject("Fn::GetAtt" ->
JsArray(
JsString("cacheSecurityGroup"),
JsString("GroupId"))
))))),
"Engine" -> JsString("redis"),
"NumCacheNodes" -> JsString("1")
)
)
)
Seq[Resource[_]](cache).toJson should be(expected)
}
}
}

0 comments on commit 8dec124

Please sign in to comment.