rubycfn 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c09925e14474150813c8cc1fc68f659c2fd9b4f6
4
- data.tar.gz: 147d961011de3e4452b273cd9d7192fa14bfa50a
3
+ metadata.gz: 7d01bd17b4d8c71bd2377cbee3606eddb28778df
4
+ data.tar.gz: 7d92a19ab91e083aed1492c4b0a00f74b01896d4
5
5
  SHA512:
6
- metadata.gz: a2d9cc012275a915b20b7ceaaf952d40d741d74b1efb5b22f5d84c62d448e000f9ad021607a53a12ed4e94d252331ece33cb6725fb3ce0af9a90e3c85b8d5fad
7
- data.tar.gz: 4f4fd5565902584c1568bb5ed8198783a2f3ba6befe96a3a20d9de65206ddf2c6b4ccc46f261ec1d9fafb65d3fea5e26e2aa19c2cd3ad68bb260508c9293d985
6
+ metadata.gz: d3708591c58295896ef5a5b46924eead40ace9744a800a52361842d6e6057f4639bc87f13ee2bc80e50dc7e879b3f8fd51a8687e8e9bb2c1a5c37c6eab9191e8
7
+ data.tar.gz: 9174d991980b0ec38e0b2d92894f9de68307c1f0fc82f14b0fdcad7d347bd412ba61d319d108ecb2c1f2a11b930ad152fa7f13a5e08aba25c3b14fda516af831
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubycfn (0.1.1)
4
+ rubycfn (0.1.2)
5
5
  activesupport (~> 5.1.5)
6
6
  dotenv (~> 2.4.0)
7
7
  json (~> 2.1.0)
data/README.md CHANGED
@@ -12,7 +12,7 @@ or, create a Gemfile with this content:
12
12
  ```
13
13
  source "https://rubygems.org"
14
14
 
15
- gem "rubycfn", "~> 0.1.1"
15
+ gem "rubycfn", "~> 0.1.2"
16
16
 
17
17
  ```
18
18
 
@@ -0,0 +1 @@
1
+ require_relative "vpc"
@@ -0,0 +1,89 @@
1
+ module RubyCfn
2
+ module VPC
3
+ def self.[](prefix, suffix, &block)
4
+ Module.new do
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+
9
+ def validate_instance_tenancy(value)
10
+ unless ["", 'default', 'dedicated'].include? value
11
+ raise "Expected instance_tenancy to be within `default` or `dedicated`. Received `#{value}`"
12
+ end
13
+ value
14
+ end
15
+
16
+ variable :cidr_block,
17
+ default: "10.0.0.0/16"
18
+ variable :enable_dns_support,
19
+ default: true
20
+ variable :enable_dns_hostnames,
21
+ default: true
22
+ variable :instance_tenancy,
23
+ filter: :validate_instance_tenancy
24
+ # TODO: Move to separate compound resource
25
+ # variable :ipv6,
26
+ # default: false
27
+ # variable :subnets,
28
+ # default: 3
29
+ # variable :subnet_ip_addresses,
30
+ # default: 256
31
+
32
+ yield self if block_given? # Variable overrides
33
+
34
+ resource "#{prefix}_vpc#{suffix}",
35
+ type: "AWS::EC2::VPC" do |r, index|
36
+ r.property(:cidr_block) { cidr_block }
37
+ r.property(:enable_dns_support) { enable_dns_support }
38
+ r.property(:enable_dns_hostnames) { enable_dns_hostnames }
39
+ r.property(:instance_tenancy) { instance_tenancy } unless instance_tenancy.empty?
40
+ end
41
+
42
+ resource "#{prefix}_internet_gateway#{suffix}",
43
+ type: "AWS::EC2::InternetGateway"
44
+
45
+ resource "#{prefix}_route#{suffix}",
46
+ type: "AWS::EC2::Route" do |r, index|
47
+ r.property(:destination_cidr_block) { "0.0.0.0/0" }
48
+ r.property(:gateway_id) { "#{prefix}_internet_gateway#{suffix}".cfnize.ref }
49
+ r.property(:route_table_id) { "#{prefix}_route_table#{suffix}".cfnize.ref }
50
+ end
51
+
52
+ resource "#{prefix}_route_table#{suffix}",
53
+ type: "AWS::EC2::RouteTable" do |r, index|
54
+ r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
55
+ end
56
+
57
+ resource "#{prefix}_vpc_gateway_attachment#{suffix}",
58
+ type: "AWS::EC2::VPCGatewayAttachment" do |r, index|
59
+ r.property(:internet_gateway_id) { "#{prefix}_internet_gateway#{suffix}".cfnize.ref }
60
+ r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
61
+ end
62
+
63
+ # TODO: Move to separate compound resource
64
+ #subnets.times do |i|
65
+ # resource "#{prefix}_subnet#{suffix}#{i == 0 ? "" : i+1}",
66
+ # type: "AWS::EC2::Subnet",
67
+ # compound: true do |r, index|
68
+ # r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
69
+ # r.property(:cidr_block) { ["#{prefix}_vpc#{suffix}".cfnize.ref("CidrBlock"), subnets.to_s, ((Math.log(subnet_ip_addresses)/Math.log(2)).floor).to_s].fncidr.fnselect(i) }
70
+ # #if ipv6 == "true"
71
+ # # r.property(:ipv6_cidr_block) do
72
+ # # .. todo ..
73
+ # # end
74
+ # #end
75
+ # end
76
+ #end
77
+
78
+ #if ipv6 == "true"
79
+ # resource "#{prefix}_ipv6_cidr_block#{suffix}",
80
+ # type: "AWS::EC2::VPCCidrBlock" do |r, index|
81
+ # r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
82
+ # r.property(:amazon_provided_ipv6_cidr_block) { true }
83
+ # end
84
+ #end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
data/lib/compound.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative "compound/vpc"
@@ -1,4 +1,4 @@
1
1
  # Rubycfn version
2
2
  module Rubycfn
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.2"
4
4
  end
data/lib/rubycfn.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require "neatjson"
3
3
  require "json"
4
4
  require "rubycfn/version"
5
+ require "compound/resources"
5
6
  require 'active_support/concern'
6
7
 
7
8
  @depends_on = []
@@ -9,6 +10,7 @@ require 'active_support/concern'
9
10
  @outputs = {}
10
11
  @parameters = {}
11
12
  @properties = {}
13
+ @mappings = {}
12
14
  @resources = {}
13
15
  @variables = {}
14
16
  @global_variables = {}
@@ -59,6 +61,22 @@ class String
59
61
  end
60
62
 
61
63
  class Array
64
+ def fncidr
65
+ {
66
+ "Fn::Cidr": self
67
+ }
68
+ end
69
+ alias_method :cidr, :fncidr
70
+
71
+ def fnfindinmap(name = nil)
72
+ self.unshift(name.cfnize) if name
73
+ {
74
+ "Fn::FindInMap": self
75
+ }
76
+ end
77
+ alias_method :find_in_map, :fnfindinmap
78
+ alias_method :findinmap, :fnfindinmap
79
+
62
80
  def fnjoin(separator = "")
63
81
  {
64
82
  "Fn::Join": [
@@ -93,6 +111,15 @@ class ::Hash
93
111
  def compact
94
112
  delete_if { |k, v| v.nil? }
95
113
  end
114
+
115
+ def fnselect(index = 0)
116
+ {
117
+ "Fn::Select": [
118
+ index,
119
+ self
120
+ ]
121
+ }
122
+ end
96
123
  end
97
124
 
98
125
  module Rubycfn
@@ -115,6 +142,24 @@ module Rubycfn
115
142
  end
116
143
  end
117
144
 
145
+ def self.mapping(name, arguments = {})
146
+ raise "`name` is required for mapping." unless arguments[:name]
147
+ unless arguments[:data]
148
+ %w(key value).each do |k|
149
+ raise "`#{k}` is required for mapping, unless a `data` hash is passed." unless arguments[k.to_sym]
150
+ end
151
+ end
152
+
153
+ name = name.to_s.cfnize
154
+ kv_pairs = arguments[:data] ? arguments[:data] : { "#{arguments[:key]}": "#{arguments[:value]}" }
155
+ res = {
156
+ "#{name}": {
157
+ "#{arguments[:name]}": kv_pairs
158
+ }
159
+ }
160
+ TOPLEVEL_BINDING.eval("@mappings = @mappings.deep_merge(#{res})")
161
+ end
162
+
118
163
  def self.parameter(name, arguments)
119
164
  name = name.to_s.cfnize
120
165
  arguments[:type] ||= "String"
@@ -151,6 +196,7 @@ module Rubycfn
151
196
  arguments[:value] ||= ""
152
197
  arguments[:required] ||= false
153
198
  arguments[:global] ||= false
199
+ arguments[:filter] ||= nil
154
200
 
155
201
  if arguments[:value].empty?
156
202
  arguments[:value] = arguments[:default]
@@ -161,6 +207,10 @@ module Rubycfn
161
207
  end
162
208
  end
163
209
 
210
+ if arguments[:filter]
211
+ arguments[:value] = self.send(arguments[:filter], arguments[:value])
212
+ end
213
+
164
214
  res = {
165
215
  "#{name}": arguments[:value]
166
216
  }
@@ -197,11 +247,12 @@ module Rubycfn
197
247
 
198
248
  def self.resource(name, arguments, &block)
199
249
  arguments[:amount] ||= 1
250
+ origname = name.to_s
200
251
  name = name.to_s.cfnize
201
252
  arguments[:amount].times do |i|
202
253
  resource_suffix = i == 0 ? "" : "#{i+1}"
203
254
  if arguments[:type].class == Module
204
- send("include", arguments[:type][name, resource_suffix, &block])
255
+ send("include", arguments[:type][origname, resource_suffix, &block])
205
256
  else
206
257
  yield self, i if block_given?
207
258
  res = {
@@ -228,10 +279,11 @@ module Rubycfn
228
279
  skeleton = { "AWSTemplateFormatVersion": "2010-09-09" }
229
280
  skeleton = JSON.parse(skeleton.to_json)
230
281
  skeleton.merge!(Description: TOPLEVEL_BINDING.eval("@description"))
282
+ skeleton.merge!(Mappings: sort_json(TOPLEVEL_BINDING.eval("@mappings")))
231
283
  skeleton.merge!(Parameters: sort_json(TOPLEVEL_BINDING.eval("@parameters")))
232
284
  skeleton.merge!(Resources: sort_json(TOPLEVEL_BINDING.eval("@resources")))
233
285
  skeleton.merge!(Outputs: sort_json(TOPLEVEL_BINDING.eval("@outputs")))
234
- TOPLEVEL_BINDING.eval("@variables = @resources = @outputs = @properties = @parameters = {}")
286
+ TOPLEVEL_BINDING.eval("@variables = @resources = @outputs = @properties = @mappings = @parameters = {}")
235
287
  TOPLEVEL_BINDING.eval("@depends_on = []")
236
288
  TOPLEVEL_BINDING.eval("@description = ''")
237
289
  JSON.pretty_generate(skeleton.recursive_compact)
@@ -11,6 +11,6 @@ Module.constants.select do |mod|
11
11
  end
12
12
 
13
13
  stacks.each do |stack_name, stack|
14
- puts "- Saved #{stack_name} to build/#{stack_name.downcase}.json"
15
- File.open("build/#{stack_name.downcase}.json", "w") { |f| f.write(stack) }
14
+ puts "- Saved #{stack_name} to build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json"
15
+ File.open("build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json", "w") { |f| f.write(stack) }
16
16
  end
@@ -20,6 +20,24 @@ module <%= name %>Stack
20
20
  r.property(:name) { example_variable }
21
21
  end
22
22
 
23
+ # Example VPC, creates VPC, IGW, Route, and VPCGatewayAttachment
24
+ # Settable variables:
25
+ # - cidr_block (defaults to 10.0.0.0/16)
26
+ # - enable_dns_support (boolean, default true)
27
+ # - enable_dns_hostnames (boolean, default true)
28
+ # - instance_tenancy (`default` or `dedicated`)
29
+ resource :my_first,
30
+ type: RubyCfn::VPC do |r|
31
+ r.set(:cidr_block) { "10.1.0.0/16" }
32
+ end
33
+ variable :cidr_block,
34
+ default: "10.0.0.0/16"
35
+ variable :enable_dns_support,
36
+ default: true
37
+ variable :enable_dns_hostnames,
38
+ default: true
39
+ variable :instance_tenancy,
40
+ filter: :validate_instance_tenancy
23
41
  # Example resource, dynamically generated name
24
42
  resource :my_example_s3_bucket,
25
43
  type: "AWS::S3::Bucket"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubycfn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dennis Vink
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-29 00:00:00.000000000 Z
11
+ date: 2018-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: neatjson
@@ -263,6 +263,9 @@ files:
263
263
  - Rakefile
264
264
  - bin/rubycfn
265
265
  - lib/cli_methods.rb
266
+ - lib/compound.rb
267
+ - lib/compound/resources.rb
268
+ - lib/compound/vpc.rb
266
269
  - lib/rubycfn.rb
267
270
  - lib/rubycfn/version.rb
268
271
  - rubycfn.gemspec