momo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +2 -0
- data/bin/momo +43 -0
- data/lib/momo.rb +40 -0
- data/lib/momo/cfl.rb +24 -0
- data/lib/momo/funccall.rb +19 -0
- data/lib/momo/mapping.rb +29 -0
- data/lib/momo/momoscope.rb +50 -0
- data/lib/momo/parameter.rb +11 -0
- data/lib/momo/reference.rb +16 -0
- data/lib/momo/resource.rb +161 -0
- data/lib/momo/stack.rb +143 -0
- data/lib/momo/version.rb +3 -0
- data/momo.gemspec +31 -0
- data/spec/momo_config_spec.rb +30 -0
- data/spec/momo_spec.rb +22 -0
- metadata +180 -0
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.DS_Store
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 David Siaw (via Travis CI)
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Momo Cloudformation template builder
|
2
|
+
|
3
|
+
Let's face it. Amazon Cloudformation Templates are shit. Amazon Web Services does not know how to make proper representations. Using JSON to call functions and create if statements is like cutting pies with a holepuncher and a waterhose. Its messy, it wastes time and its about as hygenic as drinking mud. But its the most efficient way to craft a piece of cloud infrastructure before you hand in your resignation and party the rest of your life away.
|
4
|
+
|
5
|
+
Momo solves this problem by allowing you to make concise templates using Ruby and giving you all the for loops and if conditions in their best form, and not use the stupid condition shit that makes DeMorgan roll in his grave.
|
6
|
+
|
7
|
+
Momo is called momo because we here at MObingi made it, and momo is the word for peach in Japanese, which is quite tasty.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'momo'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install momo
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Here's a basic way of using momo
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'momo'
|
29
|
+
|
30
|
+
template = cfl do
|
31
|
+
# Make a VPC
|
32
|
+
vpc = make "AWS::EC2::VPC" do
|
33
|
+
CidrBlock "10.0.0.0/16"
|
34
|
+
EnableDnsSupport true
|
35
|
+
EnableDnsHostnames true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Write the VPC id as output
|
39
|
+
output vpc
|
40
|
+
end
|
41
|
+
|
42
|
+
# Output the template as JSON.
|
43
|
+
puts template.templatize()
|
44
|
+
```
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
1. Fork it ( https://github.com/mobingilabs/momo/fork )
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
50
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
52
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/momo
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'momo'
|
3
|
+
require 'io/console'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'pp'
|
6
|
+
require 'trollop'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
opts = Trollop::options do
|
10
|
+
version "momo v1.0 (c) David Siaw"
|
11
|
+
banner <<-ENDOFBANNER
|
12
|
+
Usage:
|
13
|
+
momo [options] template
|
14
|
+
|
15
|
+
Options:
|
16
|
+
ENDOFBANNER
|
17
|
+
opt :name, "Name stack (only used when creating stack)", short: "n", default: "mystack"
|
18
|
+
opt :display, "Display template JSON", short: "d"
|
19
|
+
opt :create, "Create stack", short: "m"
|
20
|
+
opt :check, "Run verification on template", short: "c"
|
21
|
+
opt :profile, "AWS credential profile to use", short: "p", default: "DEVELOPMENT"
|
22
|
+
opt :region, "AWS region to run your template", short: "r", default: "ap-northeast-1"
|
23
|
+
end
|
24
|
+
|
25
|
+
template = cfl do
|
26
|
+
eval File.read(ARGV[0])
|
27
|
+
end
|
28
|
+
|
29
|
+
puts template.templatize() if opts[:display]
|
30
|
+
|
31
|
+
if opts[:check]
|
32
|
+
res = checkcfl(opts[:profile], opts[:region], template.templatize())
|
33
|
+
|
34
|
+
res.parameters.each do |param|
|
35
|
+
puts "Parameter: #{param.parameter_key} Default: #{param.default_value} Desc: #{param.description}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if opts[:create]
|
40
|
+
res = runcfl(opts[:profile], opts[:region], opts[:name], template.templatize())
|
41
|
+
puts "Created stack:"
|
42
|
+
puts res.stack_id
|
43
|
+
end
|
data/lib/momo.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "momo/version"
|
2
|
+
require 'aws-sdk-core'
|
3
|
+
require 'yaml'
|
4
|
+
require 'JSON'
|
5
|
+
|
6
|
+
require 'momo/cfl'
|
7
|
+
require 'momo/reference'
|
8
|
+
require 'momo/funccall'
|
9
|
+
require 'momo/momoscope'
|
10
|
+
require 'momo/parameter'
|
11
|
+
require 'momo/resource'
|
12
|
+
require 'momo/mapping'
|
13
|
+
require 'momo/stack'
|
14
|
+
|
15
|
+
|
16
|
+
def cfl(&block)
|
17
|
+
Momo::CFL.new(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def checkcfl(profile, region, template)
|
21
|
+
|
22
|
+
cf = Aws::CloudFormation::Client.new(
|
23
|
+
region: region,
|
24
|
+
profile: profile)
|
25
|
+
|
26
|
+
cf.validate_template(template_body: template)
|
27
|
+
end
|
28
|
+
|
29
|
+
def runcfl(profile, region, name, template)
|
30
|
+
|
31
|
+
cf = Aws::CloudFormation::Client.new(
|
32
|
+
region: region,
|
33
|
+
profile: profile)
|
34
|
+
|
35
|
+
cf.create_stack(
|
36
|
+
stack_name: name,
|
37
|
+
template_body: template)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
data/lib/momo/cfl.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "momo/stack.rb"
|
2
|
+
|
3
|
+
module Momo
|
4
|
+
class CFL
|
5
|
+
def initialize(&block)
|
6
|
+
@stack = Stack.new(&block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def templatize()
|
10
|
+
|
11
|
+
template = {"AWSTemplateFormatVersion" => "2010-09-09"}
|
12
|
+
template["Description"] = @stack.description
|
13
|
+
|
14
|
+
template["Mappings"] = @stack.templatize_mappings
|
15
|
+
template["Resources"] = @stack.templatize_resources
|
16
|
+
template["Parameters"] = @stack.templatize_params if @stack.parameters.length > 0
|
17
|
+
template["Outputs"] = @stack.templatize_outputs if @stack.outputs.length > 0
|
18
|
+
|
19
|
+
template.to_json
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module Momo
|
3
|
+
class FuncCall
|
4
|
+
def initialize(name, *args)
|
5
|
+
@name = name
|
6
|
+
@args = []
|
7
|
+
args.each do |arg|
|
8
|
+
@args << Momo.resolve(arg)
|
9
|
+
end
|
10
|
+
if @args.length == 1
|
11
|
+
@args = @args[0]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def representation
|
16
|
+
{@name => @args}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/momo/mapping.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'momo/momoscope'
|
2
|
+
|
3
|
+
module Momo
|
4
|
+
class MappingRow < MomoScope
|
5
|
+
attr_accessor :values
|
6
|
+
|
7
|
+
def initialize(&block)
|
8
|
+
@values = {}
|
9
|
+
instance_eval(&block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def item(name, value)
|
13
|
+
@values[name] = value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Mapping < MomoScope
|
18
|
+
attr_accessor :major_keys
|
19
|
+
|
20
|
+
def initialize(&block)
|
21
|
+
@major_keys = {}
|
22
|
+
instance_eval(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def key(name, &block)
|
26
|
+
@major_keys[name] = MappingRow.new(&block).values
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
module Momo
|
3
|
+
|
4
|
+
def Momo.resolve(something, options={})
|
5
|
+
|
6
|
+
if something.is_a? String or
|
7
|
+
something.is_a? TrueClass or
|
8
|
+
something.is_a? FalseClass or
|
9
|
+
something.is_a? Numeric
|
10
|
+
return something
|
11
|
+
elsif something.is_a? Array
|
12
|
+
result = []
|
13
|
+
something.each do |elem|
|
14
|
+
result << Momo.resolve(elem)
|
15
|
+
end
|
16
|
+
return result
|
17
|
+
elsif something.is_a? Hash
|
18
|
+
result = {}
|
19
|
+
something.each do |key, value|
|
20
|
+
result[key] = Momo.resolve(value)
|
21
|
+
end
|
22
|
+
return result
|
23
|
+
elsif something.is_a? Resource
|
24
|
+
return { "Ref" => something.name }
|
25
|
+
elsif something.is_a? Reference
|
26
|
+
return something.representation
|
27
|
+
elsif something.is_a? FuncCall
|
28
|
+
return something.representation
|
29
|
+
elsif something.is_a? Parameter
|
30
|
+
return { "Ref" => something.name }
|
31
|
+
else
|
32
|
+
raise "Invalid var: '#{something}' in #{options[:resource]}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class MomoScope
|
37
|
+
|
38
|
+
def call(name, *args)
|
39
|
+
FuncCall.new(name, *args)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ref(resource)
|
43
|
+
Reference.new(resource)
|
44
|
+
end
|
45
|
+
|
46
|
+
def lookup(map_name, key, item)
|
47
|
+
call("Fn::FindInMap", map_name, key, item)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module Momo
|
2
|
+
|
3
|
+
class Resource < MomoScope
|
4
|
+
|
5
|
+
attr_accessor :type, :name, :props, :metadata, :dependencies, :deletion_policy
|
6
|
+
|
7
|
+
def initialize(type, name)
|
8
|
+
@type = type
|
9
|
+
@name = name
|
10
|
+
@metadata = nil
|
11
|
+
@props = {}
|
12
|
+
@dependencies = []
|
13
|
+
@complete = false
|
14
|
+
@deletion_policy = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(name, *args, &block)
|
18
|
+
|
19
|
+
if /^[[:upper:]]/.match(name) == nil
|
20
|
+
raise "Invalid resource name: #{name}"
|
21
|
+
end
|
22
|
+
|
23
|
+
if !@complete
|
24
|
+
@props[name] = Momo.resolve(args[0], resource: name)
|
25
|
+
else
|
26
|
+
FuncCall.new "Fn::GetAtt", "#{@name}", "#{name}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_deletion_policy(value)
|
31
|
+
@deletion_policy = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def complete!
|
35
|
+
@complete = true
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_metadata!
|
39
|
+
|
40
|
+
if !@metadata
|
41
|
+
@metadata = {}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def init_cfinit!
|
46
|
+
init_metadata!
|
47
|
+
|
48
|
+
if !@metadata["AWS::CloudFormation::Init"]
|
49
|
+
@metadata["AWS::CloudFormation::Init"] = {}
|
50
|
+
end
|
51
|
+
|
52
|
+
if !@metadata["AWS::CloudFormation::Init"]["config"]
|
53
|
+
@metadata["AWS::CloudFormation::Init"]["config"] = {
|
54
|
+
"packages" => {},
|
55
|
+
"groups" => {},
|
56
|
+
"users" => {},
|
57
|
+
"sources" => {},
|
58
|
+
"files" => {},
|
59
|
+
"commands" => {},
|
60
|
+
"services" => {}
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def init_group(group)
|
66
|
+
init_cfinit!
|
67
|
+
if !@metadata["AWS::CloudFormation::Init"]["config"][group]
|
68
|
+
@metadata["AWS::CloudFormation::Init"]["config"][group] = {}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_thing(group, name, thing)
|
73
|
+
init_group(group)
|
74
|
+
|
75
|
+
if !@metadata["AWS::CloudFormation::Init"]["config"][group][name]
|
76
|
+
@metadata["AWS::CloudFormation::Init"]["config"][group][name] = []
|
77
|
+
end
|
78
|
+
|
79
|
+
@metadata["AWS::CloudFormation::Init"]["config"][group][name] << thing
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def set_thing(group, subgroup, name, thing)
|
84
|
+
init_group(group)
|
85
|
+
|
86
|
+
if !@metadata["AWS::CloudFormation::Init"]["config"][group][subgroup]
|
87
|
+
@metadata["AWS::CloudFormation::Init"]["config"][group][subgroup] = {}
|
88
|
+
end
|
89
|
+
|
90
|
+
@metadata["AWS::CloudFormation::Init"]["config"][group][subgroup][name] = thing
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_thing2(group, name, thing)
|
94
|
+
init_group(group)
|
95
|
+
|
96
|
+
@metadata["AWS::CloudFormation::Init"]["config"][group][name] = thing
|
97
|
+
end
|
98
|
+
|
99
|
+
def yum(package)
|
100
|
+
set_thing("packages", "yum", package, [])
|
101
|
+
end
|
102
|
+
|
103
|
+
def gem(package)
|
104
|
+
set_thing("packages", "rubygems", package, [])
|
105
|
+
end
|
106
|
+
|
107
|
+
def rpm(package)
|
108
|
+
set_thing("packages", "rpm", package, [])
|
109
|
+
end
|
110
|
+
|
111
|
+
def file(name, options={})
|
112
|
+
info = {
|
113
|
+
"content" => "",
|
114
|
+
"group" => "root",
|
115
|
+
"owner" => "root",
|
116
|
+
"mode" => "000600",
|
117
|
+
"context" => {},
|
118
|
+
}
|
119
|
+
|
120
|
+
if options[:content] and options[:source]
|
121
|
+
raise "Momo CFL Resource: Please specify only file content or source and not both"
|
122
|
+
end
|
123
|
+
|
124
|
+
info["content"] = options[:content] if options[:content]
|
125
|
+
info["source"] = options[:source] if options[:source]
|
126
|
+
info["group"] = options[:group] if options[:group]
|
127
|
+
info["mode"] = options[:mode] if options[:mode]
|
128
|
+
info["owner"] = options[:owner] if options[:owner]
|
129
|
+
info["context"] = Momo.resolve(options[:context]) if options[:context]
|
130
|
+
|
131
|
+
set_thing2("files", name, info)
|
132
|
+
end
|
133
|
+
|
134
|
+
def service(service_name)
|
135
|
+
set_thing("services", "sysvinit", service_name, {enabled: true, ensureRunning: true})
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
def tag(key, value, options={})
|
140
|
+
if !@props["Tags"]
|
141
|
+
@props["Tags"] = []
|
142
|
+
end
|
143
|
+
|
144
|
+
theTag = { "Key" => key, "Value" => Momo.resolve(value) }
|
145
|
+
theTag["PropagateAtLaunch"] = options[:propagate_at_launch] if options[:propagate_at_launch]
|
146
|
+
|
147
|
+
@props["Tags"] << theTag
|
148
|
+
end
|
149
|
+
|
150
|
+
def depends_on(resource)
|
151
|
+
if resource.is_a? String
|
152
|
+
@dependencies << args[0]
|
153
|
+
elsif resource.is_a? Resource
|
154
|
+
@dependencies << resource.name
|
155
|
+
else
|
156
|
+
raise "Invalid argument to depends_on: #{resource[0]}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
data/lib/momo/stack.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'momo/momoscope'
|
2
|
+
|
3
|
+
module Momo
|
4
|
+
|
5
|
+
class Stack < MomoScope
|
6
|
+
|
7
|
+
attr_accessor :resources, :parameters, :outputs
|
8
|
+
|
9
|
+
def initialize(&block)
|
10
|
+
raise "Stack expects a block" unless block
|
11
|
+
|
12
|
+
@description = "No description"
|
13
|
+
@resources = {}
|
14
|
+
@parameters = {}
|
15
|
+
@outputs = {}
|
16
|
+
@mappings = {}
|
17
|
+
|
18
|
+
@names = {}
|
19
|
+
|
20
|
+
@ids = {}
|
21
|
+
instance_eval(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def description(*args)
|
26
|
+
if (args.length == 1)
|
27
|
+
@description = args[0]
|
28
|
+
else
|
29
|
+
@description
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def make_default_resource_name (type)
|
34
|
+
match = /\:?\:?([a-zA-Z]+)$/.match(type)
|
35
|
+
name = match.captures[0]
|
36
|
+
|
37
|
+
if !@names[name]
|
38
|
+
@names[name] = 1
|
39
|
+
else
|
40
|
+
@names[name] += 1
|
41
|
+
end
|
42
|
+
|
43
|
+
"#{name}#{@names[name]}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def make_random_string
|
47
|
+
id = ""
|
48
|
+
loop do
|
49
|
+
o = [('A'..'Z'), ('0'..'9')].map { |i| i.to_a }.flatten
|
50
|
+
id = (1...20).map { o[rand(o.length)] }.join
|
51
|
+
break if !@ids.has_key?(id)
|
52
|
+
end
|
53
|
+
|
54
|
+
@ids[id] = true
|
55
|
+
id
|
56
|
+
end
|
57
|
+
|
58
|
+
def param(name, options={})
|
59
|
+
@parameters[name] = Parameter.new(name, options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def make(type, options = {}, &block)
|
63
|
+
|
64
|
+
name = options[:name]
|
65
|
+
name = make_default_resource_name(type) if !name
|
66
|
+
|
67
|
+
resource = Resource.new(type, name)
|
68
|
+
resource.instance_eval(&block) if block
|
69
|
+
resource.complete!
|
70
|
+
|
71
|
+
raise "Resource #{name} already exists" if @resources.has_key? resource.name
|
72
|
+
@resources[resource.name] = resource
|
73
|
+
resource
|
74
|
+
end
|
75
|
+
|
76
|
+
def output(name, res)
|
77
|
+
if res.is_a? Resource
|
78
|
+
@outputs[name] = { "Ref" => res.name }
|
79
|
+
elsif res.is_a? String
|
80
|
+
@props[name] = res
|
81
|
+
else
|
82
|
+
raise "Invalid var: #{res}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def mapping(name, &block)
|
87
|
+
@mappings[name] = Mapping.new(&block).major_keys
|
88
|
+
end
|
89
|
+
|
90
|
+
def templatize_mappings
|
91
|
+
@mappings
|
92
|
+
end
|
93
|
+
|
94
|
+
def templatize_resources
|
95
|
+
temp = {}
|
96
|
+
@resources.each do |name, res|
|
97
|
+
temp[name] = {"Type" => res.type, "Properties" => {}}
|
98
|
+
res.props.each do |propname, prop|
|
99
|
+
temp[name]["Properties"][propname] = prop
|
100
|
+
end
|
101
|
+
|
102
|
+
if res.metadata
|
103
|
+
temp[name]["Metadata"] = res.metadata
|
104
|
+
end
|
105
|
+
|
106
|
+
if res.dependencies.length != 0
|
107
|
+
temp[name]["DependsOn"] = res.dependencies
|
108
|
+
end
|
109
|
+
|
110
|
+
if res.deletion_policy
|
111
|
+
temp[name]["DeletionPolicy"] = res.deletion_policy
|
112
|
+
end
|
113
|
+
end
|
114
|
+
temp
|
115
|
+
end
|
116
|
+
|
117
|
+
def templatize_outputs
|
118
|
+
temp = {}
|
119
|
+
@outputs.each do |name, res|
|
120
|
+
temp[name] = {"Value" => res}
|
121
|
+
end
|
122
|
+
temp
|
123
|
+
end
|
124
|
+
|
125
|
+
def templatize_params
|
126
|
+
temp = {}
|
127
|
+
@parameters.each do |name, param|
|
128
|
+
typeConv = {
|
129
|
+
string: "String",
|
130
|
+
number: "Number",
|
131
|
+
list: "List"
|
132
|
+
}
|
133
|
+
|
134
|
+
temp[name] = {"Type" => typeConv[param.options[:type]]}
|
135
|
+
temp[name]["NoEcho"] = true unless param.options[:no_echo] == false
|
136
|
+
temp[name]["Description"] = param.options[:description] if param.options.has_key? :description
|
137
|
+
temp[name]["Default"] = param.options[:default] if param.options.has_key? :default
|
138
|
+
temp[name]["AllowedValues"] = param.options[:allowed] if param.options.has_key? :allowed
|
139
|
+
end
|
140
|
+
temp
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/momo/version.rb
ADDED
data/momo.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'momo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "momo"
|
8
|
+
spec.version = Momo::VERSION
|
9
|
+
spec.authors = ["David Siaw"]
|
10
|
+
spec.email = ["david.siaw@mobingi.com"]
|
11
|
+
spec.summary = %q{Mobingi Deployment System}
|
12
|
+
spec.description = %q{Deploys Cloud Servers}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activesupport"
|
22
|
+
spec.add_dependency "aws-sdk-core"
|
23
|
+
spec.add_dependency "json"
|
24
|
+
spec.add_dependency "trollop"
|
25
|
+
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "rspec"
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'momo'
|
2
|
+
|
3
|
+
describe Momo::MomoConfig do
|
4
|
+
it "Config file does not exist" do
|
5
|
+
conf = Momo::MomoConfig.new ("nyan.config")
|
6
|
+
expect(conf.test_config).to eq(false)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "Config file does not exist. Key should be empty" do
|
10
|
+
conf = Momo::MomoConfig.new ("nyan.config")
|
11
|
+
expect(conf.aws_access_key).to eq("")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "Config file does not exist. Secret should be empty" do
|
15
|
+
conf = Momo::MomoConfig.new ("nyan.config")
|
16
|
+
expect(conf.aws_secret_key).to eq("")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "Writing to the access key should work" do
|
20
|
+
conf = Momo::MomoConfig.new ("nyan.config")
|
21
|
+
conf.aws_access_key = "abcd"
|
22
|
+
expect(conf.aws_access_key).to eq("abcd")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Writing to the secret key should work" do
|
26
|
+
conf = Momo::MomoConfig.new ("nyan.config")
|
27
|
+
conf.aws_secret_key = "abcd"
|
28
|
+
expect(conf.aws_secret_key).to eq("abcd")
|
29
|
+
end
|
30
|
+
end
|
data/spec/momo_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'momo'
|
2
|
+
|
3
|
+
describe Momo::MomoCloud do
|
4
|
+
it "Use direct reference" do
|
5
|
+
structure = momo_create do
|
6
|
+
vpc = vpc "VPC", cidr_block: "10.1.0.0/16"
|
7
|
+
gateway "Internet Gateway", vpc: vpc
|
8
|
+
end
|
9
|
+
|
10
|
+
expect(structure[:resources]["Internet Gateway"][:vpc]).to eq(structure[:resources]["VPC"])
|
11
|
+
end
|
12
|
+
|
13
|
+
it "Use indirect reference" do
|
14
|
+
structure = momo_create do
|
15
|
+
vpc "VPC", cidr_block: "10.1.0.0/16"
|
16
|
+
gateway "Internet Gateway", vpc: "VPC"
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(structure[:resources]["Internet Gateway"][:vpc]).to eq(structure[:resources]["VPC"])
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: momo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Siaw
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-07-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: aws-sdk-core
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: json
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: trollop
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '1.6'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.6'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rspec
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: Deploys Cloud Servers
|
127
|
+
email:
|
128
|
+
- david.siaw@mobingi.com
|
129
|
+
executables:
|
130
|
+
- momo
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- .gitignore
|
135
|
+
- Gemfile
|
136
|
+
- LICENSE.txt
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- bin/momo
|
140
|
+
- lib/momo.rb
|
141
|
+
- lib/momo/cfl.rb
|
142
|
+
- lib/momo/funccall.rb
|
143
|
+
- lib/momo/mapping.rb
|
144
|
+
- lib/momo/momoscope.rb
|
145
|
+
- lib/momo/parameter.rb
|
146
|
+
- lib/momo/reference.rb
|
147
|
+
- lib/momo/resource.rb
|
148
|
+
- lib/momo/stack.rb
|
149
|
+
- lib/momo/version.rb
|
150
|
+
- momo.gemspec
|
151
|
+
- spec/momo_config_spec.rb
|
152
|
+
- spec/momo_spec.rb
|
153
|
+
homepage: ''
|
154
|
+
licenses:
|
155
|
+
- MIT
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ! '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 1.8.29
|
175
|
+
signing_key:
|
176
|
+
specification_version: 3
|
177
|
+
summary: Mobingi Deployment System
|
178
|
+
test_files:
|
179
|
+
- spec/momo_config_spec.rb
|
180
|
+
- spec/momo_spec.rb
|