momo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in momo.gemspec
4
+ gemspec
@@ -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.
@@ -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
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -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
@@ -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
+
@@ -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
@@ -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,11 @@
1
+
2
+ module Momo
3
+ class Parameter
4
+ attr_accessor :name, :options
5
+
6
+ def initialize(name, options={})
7
+ @name = name
8
+ @options = options
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module Momo
3
+ class Reference
4
+ def initialize(res)
5
+ @res = res
6
+ end
7
+
8
+ def representation
9
+ {"Ref" => @res}
10
+ end
11
+
12
+ def method_missing(name, *args, &block)
13
+ puts "Ref missing #{name}"
14
+ end
15
+ end
16
+ 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
@@ -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
@@ -0,0 +1,3 @@
1
+ module Momo
2
+ VERSION = "0.1.0"
3
+ end
@@ -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
@@ -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