asteroid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ module Asteroid
2
+ module Provider
3
+ class Mock < Abstract
4
+
5
+ def self.ip_address
6
+ (0..3).to_a.map{|a| rand(255)}.join(".")
7
+ end
8
+
9
+ def initialize(config = {})
10
+ @config = config || {}
11
+ @config[:filename] ||= File.join(File.dirname(__FILE__), '../../../world.yml')
12
+
13
+ begin
14
+ @world = YAML::load_file @config[:filename]
15
+ rescue
16
+ puts "No such file #{@config[:filename]}"
17
+ @world = {}
18
+ end
19
+ end
20
+
21
+ def instances
22
+ @config[:instances] || []
23
+ end
24
+
25
+ def create_instance(server)
26
+ instance = {
27
+ name: server.generate_instance_name,
28
+ id: SecureRandom.hex(5),
29
+ ip_address: self.class.ip_address,
30
+ provider: self,
31
+ type: server.type,
32
+ server: server
33
+ }
34
+ Instance.new instance
35
+ end
36
+
37
+ def destroy_instance(instance)
38
+
39
+ end
40
+
41
+ private
42
+
43
+ def save_world
44
+ File.open(@config[:filename], 'w') do |f|
45
+ f.write @world.to_yaml
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ # :name=>"web-1c5c2972",
2
+ # :image_id=>3101918,
3
+ # :size_id=>66,
4
+ # :region_id=>4,
5
+ # :backups_active=>false,
6
+ # :ip_address=>"107.170.109.79",
7
+ # :private_ip_address=>"10.128.197.52",
8
+ # :locked=>false,
9
+ # :status=>"active",
10
+ # :created_at=>"2014-04-12T20:44:53Z"}
11
+
12
+ module Asteroid
13
+ module Provider
14
+ class VirtualBox
15
+
16
+ def initialize(options = {})
17
+ end
18
+
19
+ def self.type
20
+ :virtual_box
21
+ end
22
+
23
+ def instances
24
+ instances = `VBoxManage list vms`.split /\n/
25
+ instances.map do |line|
26
+ matches = line.match /\"(\S+)\" {(\S+)}/
27
+ name, uuid = matches[0], matches[1]
28
+ ip_address = `VBoxManage guestproperty get "#{uuid}" "/VirtualBox/GuestInfo/Net/0/V4/IP" | awk '{ print $2 }'`
29
+ {
30
+ id: uuid,
31
+ name: name,
32
+ ip_address: ip_address,
33
+ provider: self
34
+ }
35
+ end
36
+ end
37
+
38
+ def destroy_instance(instance)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,64 @@
1
+ require 'erb'
2
+
3
+ module Asteroid
4
+ class Script
5
+
6
+ def initialize(filename)
7
+ @filename = filename
8
+ end
9
+
10
+ def set_data(data)
11
+ @data = data
12
+ end
13
+
14
+ def data
15
+ @data ||= {}
16
+ end
17
+
18
+ def name
19
+ File.basename @filename
20
+ end
21
+
22
+ def file_type
23
+ @file_type ||= @filename.split('.').last
24
+ end
25
+
26
+ def yml?
27
+ file_type == "yml"
28
+ end
29
+
30
+ def aster?
31
+ file_type == "aster"
32
+ end
33
+
34
+ def template?
35
+ @filename.split('.').last == "erb"
36
+ end
37
+
38
+ def render(locals = {})
39
+ script = File.read @filename
40
+ if template?
41
+ Template.new(:erb).render(
42
+ script,
43
+ self.data.merge(locals)
44
+ )
45
+ else
46
+ script
47
+ end
48
+ end
49
+
50
+ def self.named(name)
51
+ all.select{|s| s.name == name}.first
52
+ end
53
+
54
+ def self.all
55
+ files = Dir[Asteroid::Config.script_dir + "/*"]
56
+ files.map do |filename|
57
+ new(filename)
58
+ end
59
+ end
60
+
61
+
62
+
63
+ end
64
+ end
@@ -0,0 +1,96 @@
1
+ require "active_support/hash_with_indifferent_access"
2
+ require "active_support/core_ext/hash"
3
+
4
+
5
+ module Asteroid
6
+ class Server
7
+
8
+ attr_accessor :scripts,
9
+ :configure_steps
10
+
11
+ def self.named(name)
12
+ data = YAML::load_file(Asteroid::Config.server_dir + "/#{name}.yml")
13
+ new data
14
+ end
15
+
16
+ def initialize(data = {})
17
+ data = ActiveSupport::HashWithIndifferentAccess.new(data)
18
+
19
+ @provider = if data[:provider]
20
+ Provider.named data[:provider]
21
+ else
22
+ Config.providers.first
23
+ end
24
+
25
+
26
+ @attributes = data
27
+
28
+ @config = data["config"] || {
29
+ "admin_username" => "ubuntu",
30
+ "ssh_port" => 1983
31
+ }
32
+
33
+ @default_config = data["default_instance_config"] || {
34
+ "login.username" => "root",
35
+ "ssh.port" => "22"
36
+ }
37
+ end
38
+
39
+
40
+ def name
41
+ @attributes[:name]
42
+ end
43
+
44
+ def attributes
45
+ @attributes
46
+ end
47
+
48
+ def commands
49
+ @commands
50
+ end
51
+
52
+ def [](k)
53
+ config[k.to_s]
54
+ end
55
+
56
+ def config
57
+ @config
58
+ end
59
+
60
+ def type
61
+ name.to_sym
62
+ end
63
+
64
+ def first_instance
65
+ Asteroid::Instance.all_with_type(self.type).first
66
+ end
67
+
68
+ def instance_config
69
+ @default_config
70
+ end
71
+
72
+ def ssh_key_filename
73
+ File.join Asteroid::Config.ssh_key_dir, @ssh_keys.first
74
+ end
75
+
76
+ def provider
77
+ @provider
78
+ end
79
+
80
+ def generate_instance_name(subname = nil)
81
+ "#{self.name}-#{subname || SecureRandom.hex(4)}"
82
+ end
83
+
84
+ def create_instance!(subname = nil)
85
+
86
+ #key_ids = SSHKey.all.select do |k|
87
+ # @ssh_keys.include?(k.name)
88
+ #end.map do |k|
89
+ # k.id
90
+ #end
91
+
92
+ provider.create_instance(self)
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,41 @@
1
+ require 'open-uri'
2
+
3
+ module Asteroid
4
+ class SSHKey
5
+
6
+ attr_accessor :id, :name, :ssh_pub_key
7
+
8
+ def initialize(options = {})
9
+ @id = options[:id]
10
+ @name = options[:name]
11
+ end
12
+
13
+ def exists?
14
+ names = self.class.all.map{|k| k.name }
15
+ names.include? @name
16
+ end
17
+
18
+ def self.find(name)
19
+ name = name.to_s
20
+ all.select{|k| k.name == name}.first
21
+ end
22
+
23
+ def self.all
24
+ keys = Provider.all.ssh_keys
25
+ keys.map do |key|
26
+ new id: key[:id], name: key[:name]
27
+ end
28
+ end
29
+
30
+ def save
31
+ if exists?
32
+ puts "Key exists"
33
+ else
34
+ Digitalocean::SshKey.create(
35
+ name: @name,
36
+ ssh_pub_key: URI::escape(@ssh_pub_key)
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ module Asteroid
2
+ class Template
3
+
4
+ def initialize(type = :erb)
5
+ @type = type
6
+ end
7
+
8
+ def render(text, locals = {})
9
+ if @type == :erb
10
+ render_erb(text, locals)
11
+ else
12
+ raise "Unknown teplate: #{@type}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def render_erb(text, locals = {})
19
+ ERB.new(text).result(
20
+ data = OpenStruct.new(locals).instance_eval{ binding }
21
+ )
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Asteroid
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ require File.join(File.dirname(__FILE__), *%w(.. lib asteroid))
2
+
3
+ require "minitest/autorun"
4
+
5
+
6
+ Asteroid::Config.providers << Asteroid::Provider::Mock.new
7
+
8
+
@@ -0,0 +1,18 @@
1
+ require_relative '../helper'
2
+
3
+ class TestInstance < Minitest::Test
4
+ include Asteroid
5
+
6
+ def test_get_all_instances
7
+ instances = Instance.all
8
+ assert_kind_of(Array, instances)
9
+ end
10
+
11
+ def initialize_instance
12
+ instance = Instance.new
13
+ end
14
+
15
+
16
+
17
+
18
+ end
@@ -0,0 +1,19 @@
1
+ require_relative '../helper'
2
+
3
+ class TestServer < Minitest::Test
4
+ include Asteroid
5
+
6
+ def test_create_instance_server
7
+ s = Server.new name: "web"
8
+ instance = s.create_instance!
9
+ assert_kind_of(Instance, instance)
10
+ assert_equal(instance.server, s)
11
+ end
12
+
13
+ def test_server_type
14
+ s = Server.new name: "web"
15
+ assert_equal :web, s.type
16
+ end
17
+
18
+
19
+ end
metadata ADDED
@@ -0,0 +1,241 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asteroid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sam Murphy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-ssh
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-scp
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aster
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: digitalocean
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.6'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
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
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: minitest
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: autotest
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description:
168
+ email:
169
+ - sam.murphy@gmail.com
170
+ executables:
171
+ - asteroid
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - .gitignore
176
+ - Gemfile
177
+ - LICENSE.txt
178
+ - README.md
179
+ - Rakefile
180
+ - asteroid.gemspec
181
+ - bin/asteroid
182
+ - generator/README.md
183
+ - generator/Rakefile
184
+ - generator/asteroid/servers/default.yml
185
+ - generator/config/asteroid.rb
186
+ - generator/gitignore
187
+ - generator/secrets/.keep
188
+ - generator/secrets/config/providers.rb
189
+ - generator/secrets/config/secrets.yml
190
+ - lib/asteroid.rb
191
+ - lib/asteroid/application.rb
192
+ - lib/asteroid/config.rb
193
+ - lib/asteroid/config_file.rb
194
+ - lib/asteroid/generator.rb
195
+ - lib/asteroid/instance.rb
196
+ - lib/asteroid/instance/aster.rb
197
+ - lib/asteroid/instance/command.rb
198
+ - lib/asteroid/instance/scp.rb
199
+ - lib/asteroid/instance/ssh.rb
200
+ - lib/asteroid/instance/vars.rb
201
+ - lib/asteroid/provider.rb
202
+ - lib/asteroid/provider/abstract.rb
203
+ - lib/asteroid/provider/digital_ocean.rb
204
+ - lib/asteroid/provider/mock.rb
205
+ - lib/asteroid/provider/virtual_box.rb
206
+ - lib/asteroid/script.rb
207
+ - lib/asteroid/server.rb
208
+ - lib/asteroid/ssh_key.rb
209
+ - lib/asteroid/template.rb
210
+ - lib/asteroid/version.rb
211
+ - test/helper.rb
212
+ - test/unit/test_instance.rb
213
+ - test/unit/test_server.rb
214
+ homepage: ''
215
+ licenses:
216
+ - MIT
217
+ metadata: {}
218
+ post_install_message:
219
+ rdoc_options: []
220
+ require_paths:
221
+ - lib
222
+ required_ruby_version: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - '>='
225
+ - !ruby/object:Gem::Version
226
+ version: '0'
227
+ required_rubygems_version: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - '>='
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ requirements: []
233
+ rubyforge_project:
234
+ rubygems_version: 2.2.2
235
+ signing_key:
236
+ specification_version: 4
237
+ summary: A server configuration framework
238
+ test_files:
239
+ - test/helper.rb
240
+ - test/unit/test_instance.rb
241
+ - test/unit/test_server.rb