build-cloud 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []