cloudshaper 0.0.4

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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +7 -0
  5. data/Gemfile.lock +27 -0
  6. data/LICENSE +23 -0
  7. data/README.md +162 -0
  8. data/Rakefile +9 -0
  9. data/TODO.md +7 -0
  10. data/examples/secretconfig/README.md +3 -0
  11. data/examples/secretconfig/atlas.json +5 -0
  12. data/examples/secretconfig/aws.json +6 -0
  13. data/examples/secretconfig/cloudflare.json +6 -0
  14. data/examples/secretconfig/cloudstack.json +7 -0
  15. data/examples/secretconfig/digitalocean.json +5 -0
  16. data/examples/secretconfig/dme.json +6 -0
  17. data/examples/secretconfig/heroku.json +6 -0
  18. data/examples/secretconfig/mailgun.json +5 -0
  19. data/examples/simple_app.rb +61 -0
  20. data/lib/tasks/tasks.rb +12 -0
  21. data/lib/tasks/terraform.rake +127 -0
  22. data/lib/terraform_dsl.rb +6 -0
  23. data/lib/terraform_dsl/aws/remote_s3.rb +20 -0
  24. data/lib/terraform_dsl/aws/tagging.rb +23 -0
  25. data/lib/terraform_dsl/command.rb +58 -0
  26. data/lib/terraform_dsl/module.rb +38 -0
  27. data/lib/terraform_dsl/output.rb +6 -0
  28. data/lib/terraform_dsl/provider.rb +13 -0
  29. data/lib/terraform_dsl/remote.rb +31 -0
  30. data/lib/terraform_dsl/resource.rb +44 -0
  31. data/lib/terraform_dsl/secrets.rb +29 -0
  32. data/lib/terraform_dsl/stack.rb +79 -0
  33. data/lib/terraform_dsl/stack_element.rb +62 -0
  34. data/lib/terraform_dsl/stack_module.rb +121 -0
  35. data/lib/terraform_dsl/stack_modules.rb +24 -0
  36. data/lib/terraform_dsl/stacks.rb +64 -0
  37. data/lib/terraform_dsl/variable.rb +6 -0
  38. data/lib/terraform_dsl/version.rb +3 -0
  39. data/terraform_dsl.gemspec +25 -0
  40. data/test/stack_module_test.rb +152 -0
  41. data/test/stack_test.rb +5 -0
  42. data/test/test_helper.rb +4 -0
  43. metadata +131 -0
@@ -0,0 +1,24 @@
1
+ module Terraform
2
+ # Stack module factory, register a module and provide clones of it
3
+ class StackModules
4
+ class ModuleNotFound < StandardError; end
5
+ class ModuleAlreadyRegistered < StandardError; end
6
+
7
+ class << self
8
+ def register(name, stack_module)
9
+ fail ModuleAlreadyRegistered, "#{name} is already a registered stack_module" if @stack_modules.key?(name.downcase)
10
+ @stack_modules[name.downcase] = stack_module
11
+ end
12
+
13
+ def get(stack_module_name)
14
+ fail ModuleNotFound, "#{stack_module_name} module module not found" unless @stack_modules.key?(stack_module_name.downcase)
15
+ @stack_modules[stack_module_name.downcase].clone
16
+ end
17
+
18
+ def reset!
19
+ @stack_modules ||= {}
20
+ end
21
+ end
22
+ reset!
23
+ end
24
+ end
@@ -0,0 +1,64 @@
1
+ require 'yaml'
2
+ require 'securerandom'
3
+
4
+ require 'terraform_dsl/stack'
5
+
6
+ module Terraform
7
+ # Singleton to keep track of stack templates
8
+ class Stacks
9
+ class MalformedConfig < StandardError; end
10
+ class << self
11
+ attr_reader :stacks
12
+
13
+ def load
14
+ config = ENV['STACK_CONFIG'] || 'stacks.yml'
15
+ fail 'stacks.yml must exist in root directory, or specify STACK_CONFIG pointing to stacks.yml' unless File.exist?(config)
16
+ stack_specs = YAML.load(File.read(config))
17
+ fail MalformedConfig, 'Stacks must be an array' unless stack_specs.key?('stacks') && stack_specs['stacks'].is_a?(Array)
18
+ common = stack_specs['common'] || {}
19
+ stack_specs['stacks'].each do |stack_spec|
20
+ stack = Stack.load(stack_spec.merge(common))
21
+ @stacks[stack.name] = stack
22
+ end
23
+ end
24
+
25
+ def init
26
+ config = ENV['STACK_CONFIG'] || 'stacks.yml'
27
+ fail "stacks.yaml already exists at #{File.expand_path(config)}" if File.exist?(config)
28
+ File.open(config, 'w') do |f|
29
+ f.write(YAML.dump(base_config))
30
+ end
31
+ end
32
+
33
+ def uuid
34
+ "#{Time.now.utc.to_i}_#{SecureRandom.urlsafe_base64(6)}"
35
+ end
36
+
37
+ def base_config
38
+ {
39
+ 'common' => {},
40
+ 'stacks' => [base_stack_config]
41
+ }
42
+ end
43
+
44
+ def base_stack_config
45
+ {
46
+ 'name' => 'SET_NAME',
47
+ 'uuid' => uuid,
48
+ 'description' => 'SET_A_DESCRIPTION',
49
+ 'root' => 'SET_A_TEMPLATE',
50
+ 'variables' => {}
51
+ }
52
+ end
53
+
54
+ def reset!
55
+ @stacks ||= {}
56
+ end
57
+
58
+ def dir
59
+ File.expand_path(File.join(ENV['TERRAFORM_DATA_DIR'] || 'data', 'stacks'))
60
+ end
61
+ end
62
+ reset!
63
+ end
64
+ end
@@ -0,0 +1,6 @@
1
+ require 'terraform_dsl/stack_element'
2
+
3
+ module Terraform
4
+ class Variable < StackElement
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module Terraform
2
+ VERSION = '0.0.4'
3
+ end
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'terraform_dsl/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'cloudshaper'
7
+ spec.version = Terraform::VERSION
8
+ spec.summary = 'Wrap hashicorps "terraform" in a ruby DSL for managing stack templates'
9
+ spec.description = 'Terraform DSL provides a syntax for managing terraform infrastructure entirely in git'
10
+ spec.authors = ['Dale Hamel']
11
+ spec.email = 'dale.hamel@srvthe.net'
12
+ spec.files = Dir['lib/**/*']
13
+ spec.homepage = 'https://rubygems.org/gems/terraform_dsl'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
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_runtime_dependency 'rake', '~> 10.4'
22
+
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'minitest', '~> 5.6'
25
+ end
@@ -0,0 +1,152 @@
1
+ require 'test_helper'
2
+
3
+ class StackModuleTest < Minitest::Test
4
+ include Terraform
5
+
6
+ def test_multiple_instantiations_of_module
7
+ StackModule.define 'factory_instantiation_test' do
8
+ variable(:ports) { default '22' }
9
+ resource 'aws_security_group', :a do
10
+ get(:ports).split(',').each do |port|
11
+ ingress { from_port port }
12
+ end
13
+ end
14
+ end
15
+
16
+ first = StackModules.get('factory_instantiation_test')
17
+ second = StackModules.get('factory_instantiation_test')
18
+
19
+ first.build(ports: '80')
20
+ second.build(ports: '443')
21
+
22
+ sg_first = first.elements[:resource][:aws_security_group][:a]
23
+ sg_second = second.elements[:resource][:aws_security_group][:a]
24
+
25
+ assert_equal '80', sg_first[:ingress].fetch(:from_port)
26
+ assert_equal '443', sg_second[:ingress].fetch(:from_port)
27
+ end
28
+
29
+ # it 'should register variables with default values' do
30
+ # mod = StackModule.define('variable_register_default') { variable(:name) { default 'default' } }
31
+ # mod.build
32
+
33
+ # expect(mod.variables).to be_a(Hash)
34
+ # expect(mod.variables).to include(:name)
35
+ # expect(mod.variables[:name]).to be_a(Hash)
36
+ # expect(mod.variables[:name]).to include(:default)
37
+ # expect(mod.variables[:name][:default]).to eq('default')
38
+ # end
39
+
40
+ # it 'should register variables without default values' do
41
+ # mod = StackModule.define('variable_register_nodefault') { variable(:name) {} }
42
+ # mod.build
43
+
44
+ # expect(mod.variables).to be_a(Hash)
45
+ # expect(mod.variables).to include(:name)
46
+ # expect(mod.variables[:name]).to be_a(Hash)
47
+ # expect(mod.variables[:name]).to include(:default)
48
+ # expect(mod.variables[:name][:default]).to eq('')
49
+ # end
50
+
51
+ # it 'should accept variables at runtime' do
52
+ # mod = StackModule.define('variable_override') { variable(:name) { default 'default' } }
53
+ # mod.build(name: 'not-default')
54
+
55
+ # expect(mod.variables[:name][:default]).to eql('not-default')
56
+ # end
57
+ # end
58
+
59
+ def test_register_resource
60
+ mod = StackModule.define('register_resource') { resource('aws_instance', :a) { default 'default' } }
61
+ mod.build
62
+
63
+ instance = mod.elements.fetch(:resource).fetch(:aws_instance).fetch(:a)
64
+ assert_equal 'default', instance.fetch(:default)
65
+ end
66
+
67
+ def test_register_resource_with_connections
68
+ mod = StackModule.define 'register_connection_test' do
69
+ resource 'aws_instance', :a do
70
+ connection do
71
+ user 'root'
72
+ end
73
+ end
74
+ end
75
+ mod.build
76
+
77
+ instance = mod.elements.fetch(:resource).fetch(:aws_instance).fetch(:a)
78
+ assert_equal 'root', instance.fetch(:connection).fetch(:user)
79
+ end
80
+
81
+ def test_register_resource_with_provisioners_with_connections
82
+ mod = StackModule.define 'register_provision_connection_test' do
83
+ resource 'aws_instance', :a do
84
+ provisioner 'file' do
85
+ connection do
86
+ user 'root'
87
+ end
88
+ end
89
+ end
90
+ end
91
+ mod.build
92
+
93
+ instance = mod.elements.fetch(:resource).fetch(:aws_instance).fetch(:a)
94
+ provisioner = instance.fetch(:provisioner).first
95
+ connection = provisioner.fetch(:file).fetch(:connection)
96
+ assert_equal 'root', connection.fetch(:user)
97
+ end
98
+
99
+ def test_group_attributes_into_arrays
100
+ mod = StackModule.define 'resource_scalar_variable_groups' do
101
+ resource 'aws_security_group', :a do
102
+ ingress { from_port 80 }
103
+ ingress { from_port 443 }
104
+ end
105
+ end
106
+ mod.build
107
+
108
+ sg = mod.elements.fetch(:resource).fetch(:aws_security_group).fetch(:a)
109
+ ingress = sg.fetch(:ingress)
110
+
111
+ assert_kind_of Array, ingress
112
+ assert_equal [{from_port: 80}, {from_port: 443}], ingress
113
+ end
114
+
115
+ def test_support_overriding_attributes
116
+ mod = StackModule.define 'resource_overriden_runtime_variable' do
117
+ variable(:ports) { default '22' }
118
+ resource 'aws_security_group', :a do
119
+ get(:ports).split(',').each do |port|
120
+ ingress { from_port port }
121
+ end
122
+ end
123
+ end
124
+ mod.build(ports: '22,80,443')
125
+
126
+
127
+ sg = mod.elements.fetch(:resource).fetch(:aws_security_group).fetch(:a)
128
+ ingress = sg.fetch(:ingress)
129
+ assert_equal [{from_port: "22"}, {from_port: "80"}, {from_port: "443"}], ingress
130
+ end
131
+
132
+
133
+ # it 'it should be able to access overridden default variables at runtime' do
134
+ # mod = StackModule.define 'resource_overriden_runtime_variable' do
135
+ # variable(:ports) { default '22' }
136
+ # resource 'aws_security_group', :a do
137
+ # get(:ports).split(',').each do |port|
138
+ # ingress { from_port port }
139
+ # end
140
+ # end
141
+ # end
142
+
143
+ # mod.build(ports: '22,80,443')
144
+
145
+ # sg = mod.elements[:resource][:aws_security_group][:a]
146
+ # expect(sg).to include(:ingress)
147
+ # expect(sg[:ingress]).to be_a(Array)
148
+ # expect(sg[:ingress].first).to eq(from_port: '22')
149
+ # expect(sg[:ingress].last).to eq(from_port: '443')
150
+ # end
151
+ # end
152
+ end
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+
3
+ class StackTest < Minitest::Test
4
+
5
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+
4
+ require 'terraform_dsl'
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloudshaper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Dale Hamel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.6'
55
+ description: Terraform DSL provides a syntax for managing terraform infrastructure
56
+ entirely in git
57
+ email: dale.hamel@srvthe.net
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - TODO.md
70
+ - examples/secretconfig/README.md
71
+ - examples/secretconfig/atlas.json
72
+ - examples/secretconfig/aws.json
73
+ - examples/secretconfig/cloudflare.json
74
+ - examples/secretconfig/cloudstack.json
75
+ - examples/secretconfig/digitalocean.json
76
+ - examples/secretconfig/dme.json
77
+ - examples/secretconfig/heroku.json
78
+ - examples/secretconfig/mailgun.json
79
+ - examples/simple_app.rb
80
+ - lib/tasks/tasks.rb
81
+ - lib/tasks/terraform.rake
82
+ - lib/terraform_dsl.rb
83
+ - lib/terraform_dsl/aws/remote_s3.rb
84
+ - lib/terraform_dsl/aws/tagging.rb
85
+ - lib/terraform_dsl/command.rb
86
+ - lib/terraform_dsl/module.rb
87
+ - lib/terraform_dsl/output.rb
88
+ - lib/terraform_dsl/provider.rb
89
+ - lib/terraform_dsl/remote.rb
90
+ - lib/terraform_dsl/resource.rb
91
+ - lib/terraform_dsl/secrets.rb
92
+ - lib/terraform_dsl/stack.rb
93
+ - lib/terraform_dsl/stack_element.rb
94
+ - lib/terraform_dsl/stack_module.rb
95
+ - lib/terraform_dsl/stack_modules.rb
96
+ - lib/terraform_dsl/stacks.rb
97
+ - lib/terraform_dsl/variable.rb
98
+ - lib/terraform_dsl/version.rb
99
+ - terraform_dsl.gemspec
100
+ - test/stack_module_test.rb
101
+ - test/stack_test.rb
102
+ - test/test_helper.rb
103
+ homepage: https://rubygems.org/gems/terraform_dsl
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.6
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Wrap hashicorps "terraform" in a ruby DSL for managing stack templates
127
+ test_files:
128
+ - test/stack_module_test.rb
129
+ - test/stack_test.rb
130
+ - test/test_helper.rb
131
+ has_rdoc: