build-cloud 0.0.1

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.
@@ -0,0 +1,86 @@
1
+ class BuildCloud::Subnet
2
+
3
+ include ::BuildCloud::Component
4
+
5
+ @@objects = []
6
+
7
+ def self.get_id_by_name( name )
8
+
9
+ subnet = self.search( :name => name ).first
10
+
11
+ unless subnet
12
+ raise "Couldn't get a Subnet object for #{name} - is it defined?"
13
+ end
14
+
15
+ subnet_fog = subnet.read
16
+
17
+ unless subnet_fog
18
+ raise "Couldn't get a Subnet fog object for #{name} - is it created?"
19
+ end
20
+
21
+ subnet_fog.subnet_id
22
+
23
+ end
24
+
25
+ def initialize ( fog_interfaces, log, options = {} )
26
+
27
+ @compute = fog_interfaces[:compute]
28
+ @log = log
29
+ @options = options
30
+
31
+ @log.debug( options.inspect )
32
+
33
+ required_options(:availability_zone, :cidr_block, :name)
34
+ require_one_of(:vpc_id, :vpc_name)
35
+
36
+ end
37
+
38
+ def create
39
+
40
+ return if exists?
41
+
42
+ @log.info( "Creating subnet for #{@options[:cidr_block]} ( #{@options[:name]} )" )
43
+
44
+ options = @options.dup
45
+
46
+ unless options[:vpc_id]
47
+
48
+ options[:vpc_id] = BuildCloud::VPC.get_id_by_name( options[:vpc_name] )
49
+ options.delete(:vpc_name)
50
+
51
+ end
52
+
53
+ subnet = @compute.subnets.new( options )
54
+ subnet.save
55
+
56
+ options[:tag_set].each do | tag |
57
+ attributes = {}
58
+ attributes[:resource_id] = subnet.subnet_id.to_s
59
+ attributes[:key] = tag[:key]
60
+ attributes[:value] = tag[:value]
61
+ new_tag = @compute.tags.new( attributes )
62
+ new_tag.save
63
+ end unless options[:tag_set].empty? or options[:tag_set].nil?
64
+
65
+ @log.debug( subnet.inspect )
66
+
67
+ end
68
+
69
+ def read
70
+ @compute.subnets.select { |s| s.cidr_block == @options[:cidr_block] }.first
71
+ end
72
+
73
+ alias_method :fog_object, :read
74
+
75
+ def delete
76
+
77
+ return unless exists?
78
+
79
+ @log.info( "Subnet #{@options[:name]}" )
80
+
81
+ fog_object.destroy
82
+
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,73 @@
1
+ class BuildCloud::VPC
2
+
3
+ include ::BuildCloud::Component
4
+
5
+ @@objects = []
6
+
7
+ def self.get_id_by_name( name )
8
+
9
+ vpc = self.search( :name => name ).first
10
+
11
+ unless vpc
12
+ raise "Couldn't get a VPC object for #{name} - is it defined?"
13
+ end
14
+
15
+ vpc_fog = vpc.read
16
+
17
+ unless vpc_fog
18
+ raise "Couldn't get a VPC fog object for #{name} - is it created?"
19
+ end
20
+
21
+ vpc_fog.id
22
+
23
+ end
24
+
25
+ def initialize ( fog_interfaces, log, options = {} )
26
+
27
+ @compute = fog_interfaces[:compute]
28
+ @log = log
29
+ @options = options
30
+
31
+ @log.debug( options.inspect )
32
+
33
+ required_options(:cidr_block)
34
+
35
+ end
36
+
37
+ def create
38
+
39
+ return if exists?
40
+
41
+ @log.info( "Creating new VPC for #{@options[:cidr_block]}" )
42
+
43
+ vpc = @compute.vpcs.new( @options )
44
+ vpc.save
45
+
46
+ @log.debug( vpc.inspect )
47
+
48
+ @compute.modify_vpc_attribute( vpc.id, { 'EnableDnsHostnames.Value' => true } )
49
+
50
+ end
51
+
52
+ def read
53
+ @compute.vpcs.select { |v| v.cidr_block == @options[:cidr_block] }.first
54
+ end
55
+
56
+ alias_method :fog_object, :read
57
+
58
+ def delete
59
+
60
+ return unless exists?
61
+
62
+ @log.info( "Deleting VPC for #{@options[:cidr_block]}" )
63
+
64
+ fog_object.destroy
65
+
66
+ end
67
+
68
+ def [](key)
69
+ @options[key]
70
+ end
71
+
72
+ end
73
+
@@ -0,0 +1,96 @@
1
+ class BuildCloud::Zone
2
+
3
+ include ::BuildCloud::Component
4
+
5
+ @@objects = []
6
+
7
+ def initialize ( fog_interfaces, log, options = {} )
8
+
9
+ @r53 = fog_interfaces[:r53]
10
+ @log = log
11
+ @options = options
12
+
13
+ @log.debug( options.inspect )
14
+
15
+ required_options(:domain)
16
+
17
+ end
18
+
19
+ def create
20
+
21
+ return if exists?
22
+
23
+ @log.info( "Creating zone for #{@options[:domain]}" )
24
+
25
+ options = @options.dup
26
+
27
+ zone = @r53.zones.new( options )
28
+ zone.save
29
+
30
+ if options.has_key?(:ttl)
31
+
32
+ # Change TTL of default RR sets if required:
33
+
34
+ record_sets = @r53.list_resource_record_sets( zone.id ).data[:body]['ResourceRecordSets']
35
+ changes = []
36
+
37
+ record_sets.each do |set|
38
+
39
+ next if set['TTL'].to_i == options[:ttl].to_i
40
+
41
+ rr = set['ResourceRecords']
42
+
43
+ changes << {
44
+ :action => 'DELETE',
45
+ :name => set['Name'],
46
+ :type => set['Type'],
47
+ :ttl => set['TTL'],
48
+ :resource_records => rr,
49
+ }
50
+
51
+ if( set['Type'] == 'SOA' )
52
+
53
+ # Set min TTL in SOA too
54
+
55
+ soa = rr.first.split(/\s+/)
56
+ soa[6] = options[:ttl]
57
+ rr = [ soa.join(' ') ]
58
+
59
+ end
60
+
61
+ changes << {
62
+ :action => 'CREATE',
63
+ :name => set['Name'],
64
+ :type => set['Type'],
65
+ :ttl => options[:ttl],
66
+ :resource_records => rr,
67
+ }
68
+
69
+ end
70
+
71
+ @r53.change_resource_record_sets( zone.id, changes )
72
+
73
+ end
74
+
75
+ @log.debug( zone.inspect )
76
+
77
+ end
78
+
79
+ def read
80
+ @r53.zones.select { |z| z.domain == @options[:domain] }.first
81
+ end
82
+
83
+ alias_method :fog_object, :read
84
+
85
+ def delete
86
+
87
+ return unless exists?
88
+
89
+ @log.info( "Deleting zone for #{@options[:domain]}" )
90
+
91
+ fog_object.destroy
92
+
93
+ end
94
+
95
+ end
96
+
@@ -0,0 +1,204 @@
1
+ require 'fog'
2
+ require 'yaml'
3
+ require 'pry'
4
+ require 'logger'
5
+ require 'pp'
6
+
7
+ class BuildCloud
8
+
9
+ @config
10
+ @log
11
+ @infrastructure
12
+ @mock
13
+
14
+ def initialize( options )
15
+
16
+ @log = options[:logger] or Logger.new( STDERR )
17
+ @mock = options[:mock] or false
18
+ @config = YAML::load( File.open( options[:config] ) )
19
+
20
+ if include_file = @config.delete(:include)
21
+ include_path = File.join( File.dirname( options[:config] ), include_file)
22
+
23
+ if File.exists?( include_path )
24
+ included_conf = YAML::load( File.open( include_path ) )
25
+ @config = @config.merge( included_conf )
26
+ end
27
+
28
+ end
29
+
30
+ @log.debug( @config.inspect )
31
+
32
+ new_config = recursive_interpolate_config(@config)
33
+ @config = new_config
34
+
35
+ @log.debug( @config.inspect )
36
+
37
+ connect_fog
38
+
39
+ BuildCloud::dispatch.each_pair do |component, klass|
40
+
41
+ if @config.has_key?(component)
42
+ klass.load( @config[component], @fog_interfaces, @log )
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ def pry
50
+ binding.pry
51
+ end
52
+
53
+ def find( component, options )
54
+
55
+ if BuildCloud::dispatch.has_key?( component )
56
+ BuildCloud::dispatch[component].search(options)
57
+ else
58
+ []
59
+ end
60
+
61
+ end
62
+
63
+ def all
64
+
65
+ objects = []
66
+
67
+ BuildCloud::create_order.each do |component|
68
+ next unless BuildCloud::dispatch.has_key?( component )
69
+ objects.concat BuildCloud::dispatch[component].objects()
70
+ end
71
+
72
+ objects
73
+
74
+ end
75
+
76
+ private
77
+
78
+ def self.dispatch
79
+
80
+ {
81
+ :vpcs => BuildCloud::VPC,
82
+ :internet_gateways => BuildCloud::InternetGateway,
83
+ :subnets => BuildCloud::Subnet,
84
+ :route_tables => BuildCloud::RouteTable,
85
+ :zones => BuildCloud::Zone,
86
+ :security_groups => BuildCloud::SecurityGroup,
87
+ :network_interfaces => BuildCloud::NetworkInterface,
88
+ :routes => BuildCloud::Route,
89
+ :launch_configurations => BuildCloud::LaunchConfiguration,
90
+ :load_balancers => BuildCloud::LoadBalancer,
91
+ :as_groups => BuildCloud::ASGroup,
92
+ :r53_record_sets => BuildCloud::R53RecordSet,
93
+ :rds_servers => BuildCloud::RDSServer,
94
+ :db_subnet_groups => BuildCloud::DbSubnetGroup,
95
+ :db_parameter_groups => BuildCloud::DbParameterGroup,
96
+ :cache_subnet_groups => BuildCloud::CacheSubnetGroup,
97
+ :cache_clusters => BuildCloud::CacheCluster,
98
+ :cache_parameter_groups => BuildCloud::CacheParameterGroup,
99
+ :iam_roles => BuildCloud::IAMRole,
100
+ :s3_buckets => BuildCloud::S3Bucket,
101
+ :instances => BuildCloud::Instance,
102
+ }
103
+
104
+ end
105
+
106
+ def self.create_order
107
+ [
108
+ :vpcs,
109
+ :internet_gateways,
110
+ :iam_roles,
111
+ :subnets,
112
+ :db_subnet_groups,
113
+ :cache_subnet_groups,
114
+ :route_tables,
115
+ :zones,
116
+ :security_groups,
117
+ :network_interfaces,
118
+ :routes,
119
+ :db_parameter_groups,
120
+ :rds_servers,
121
+ :cache_parameter_groups,
122
+ :cache_clusters,
123
+ :launch_configurations,
124
+ :load_balancers,
125
+ :as_groups,
126
+ :r53_record_sets,
127
+ :s3_buckets,
128
+ :instances,
129
+ ]
130
+ end
131
+
132
+ def self.search( type, options )
133
+ BuildCloud::dispatch[type].search(options)
134
+ end
135
+
136
+ def recursive_interpolate_config(h)
137
+
138
+ # Work through the given config replacing all strings matching
139
+ # %{..x..} by looking up ..x.. in the existing @config hash and
140
+ # substituting the template with the value
141
+
142
+ case h
143
+ when Hash
144
+ Hash[
145
+ h.map do |k, v|
146
+ [ k, recursive_interpolate_config(v) ]
147
+ end
148
+ ]
149
+ when Enumerable
150
+ h.map { |v| recursive_interpolate_config(v) }
151
+ when String
152
+
153
+ while h =~ /%\{(.+?)\}/
154
+ var = $1
155
+ val = ""
156
+
157
+ if @config.has_key?(var.to_sym)
158
+ val = @config[var.to_sym]
159
+ else
160
+ raise "Attempt to interpolate with non-existant key '#{var}'"
161
+ end
162
+
163
+ h.gsub!(/%\{#{var}\}/, val)
164
+
165
+ end
166
+
167
+ h
168
+
169
+ else
170
+ h
171
+ end
172
+
173
+ end
174
+
175
+ def connect_fog
176
+
177
+ @mock and Fog.mock!
178
+
179
+ fog_options = {
180
+ :aws_access_key_id => @config[:aws_access_key_id] ||= ENV['AWS_ACCESS_KEY'],
181
+ :aws_secret_access_key => @config[:aws_secret_access_key] ||= ENV['AWS_SECRET_KEY'],
182
+ :region => @config[:aws_region],
183
+ }
184
+
185
+ @fog_interfaces = {
186
+
187
+ :compute => Fog::Compute::AWS.new( fog_options ),
188
+ :s3 => Fog::Storage::AWS.new( fog_options ),
189
+ :as => Fog::AWS::AutoScaling.new( fog_options ),
190
+ :elb => Fog::AWS::ELB.new( fog_options ),
191
+ :iam => Fog::AWS::IAM.new( fog_options ),
192
+ :rds => Fog::AWS::RDS.new( fog_options ),
193
+ :elasticache => Fog::AWS::Elasticache.new( fog_options ),
194
+ :r53 => Fog::DNS::AWS.new(
195
+ :aws_access_key_id => @config[:aws_access_key_id] ||= ENV['AWS_ACCESS_KEY'],
196
+ :aws_secret_access_key => @config[:aws_secret_access_key] ||= ENV['AWS_SECRET_KEY'],
197
+ )
198
+
199
+ }
200
+
201
+ end
202
+
203
+ end
204
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: build-cloud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - The Scale Factory
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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: fog
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 1.22.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.22.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.12.6
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.9.12.6
69
+ description:
70
+ email:
71
+ - info@scalefactory.com
72
+ executables:
73
+ - build-cloud
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/build-cloud
83
+ - build-cloud.gemspec
84
+ - lib/build-cloud.rb
85
+ - lib/build-cloud/asgroup.rb
86
+ - lib/build-cloud/cachecluster.rb
87
+ - lib/build-cloud/cacheparametergroup.rb
88
+ - lib/build-cloud/cachesubnetgroup.rb
89
+ - lib/build-cloud/component.rb
90
+ - lib/build-cloud/dbparametergroup.rb
91
+ - lib/build-cloud/dbparameters.rb
92
+ - lib/build-cloud/dbsubnetgroup.rb
93
+ - lib/build-cloud/iamrole.rb
94
+ - lib/build-cloud/instance.rb
95
+ - lib/build-cloud/internetgateway.rb
96
+ - lib/build-cloud/launchconfiguration.rb
97
+ - lib/build-cloud/loadbalancer.rb
98
+ - lib/build-cloud/networkinterface.rb
99
+ - lib/build-cloud/r53recordset.rb
100
+ - lib/build-cloud/rdsserver.rb
101
+ - lib/build-cloud/route.rb
102
+ - lib/build-cloud/routetable.rb
103
+ - lib/build-cloud/s3bucket.rb
104
+ - lib/build-cloud/securitygroup.rb
105
+ - lib/build-cloud/subnet.rb
106
+ - lib/build-cloud/vpc.rb
107
+ - lib/build-cloud/zone.rb
108
+ homepage: https://github.com/scalefactory/build-cloud
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.0.14
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Tools for building resources in AWS
132
+ test_files: []