asteroid 0.0.1 → 0.0.2

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile +1 -0
  4. data/README.md +45 -4
  5. data/Rakefile +1 -0
  6. data/asteroid.gemspec +0 -1
  7. data/bin/asteroid +4 -2
  8. data/lib/asteroid.rb +11 -10
  9. data/lib/asteroid/application.rb +60 -7
  10. data/lib/asteroid/config.rb +28 -14
  11. data/lib/asteroid/file_reference.rb +102 -0
  12. data/lib/asteroid/generator.rb +0 -4
  13. data/lib/asteroid/instance.rb +29 -9
  14. data/lib/asteroid/instance/command.rb +71 -36
  15. data/lib/asteroid/instance/scp.rb +26 -0
  16. data/lib/asteroid/instance/ssh.rb +2 -1
  17. data/lib/asteroid/instance/vars.rb +5 -2
  18. data/lib/asteroid/key_reference.rb +45 -0
  19. data/lib/asteroid/provider/abstract.rb +16 -1
  20. data/lib/asteroid/provider/digital_ocean.rb +35 -6
  21. data/lib/asteroid/provider/mock.rb +36 -14
  22. data/lib/asteroid/script.rb +3 -57
  23. data/lib/asteroid/server.rb +44 -25
  24. data/lib/asteroid/template.rb +19 -7
  25. data/lib/asteroid/template/liquid.rb +0 -0
  26. data/lib/asteroid/version.rb +1 -1
  27. data/sample/.gitignore +2 -0
  28. data/sample/README.md +1 -0
  29. data/sample/Rakefile +0 -0
  30. data/sample/TODO +9 -0
  31. data/sample/asteroid/files/nginx/available_site.conf.erb +0 -0
  32. data/sample/asteroid/files/nginx/nginx.conf +1 -0
  33. data/sample/asteroid/scripts/ubuntu.aster +4 -0
  34. data/sample/asteroid/servers/default.yml +3 -0
  35. data/sample/asteroid/servers/web.yml +5 -0
  36. data/sample/config/asteroid.rb +9 -0
  37. data/test/helper.rb +18 -2
  38. data/test/unit/test_application.rb +17 -0
  39. data/test/unit/test_file_reference.rb +18 -0
  40. data/test/unit/test_instance.rb +20 -4
  41. data/test/unit/test_script_reference.rb +9 -0
  42. data/test/unit/test_server.rb +46 -2
  43. data/test/unit/test_template.rb +16 -0
  44. metadata +24 -17
  45. data/lib/asteroid/config_file.rb +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d3ce3e8c2c0efe5635f743569fa70a6cc709b52e
4
- data.tar.gz: 1f50a63fb78232511d1765201d82eb5225e7b682
3
+ metadata.gz: e5c5cc037af98984058dd5b4f265e016566f8f3f
4
+ data.tar.gz: f63bd8fd4eb00c4ae7fc2b081c6c132ff8910040
5
5
  SHA512:
6
- metadata.gz: 916902671568e85392e6faac6ee8cc499013360377a47e0cf9ebac7751902394f5a6f9e338a255e80abde8456a753b5ddb6e197ae27bae6b28fd856f4cda18e2
7
- data.tar.gz: d3656731753ee60ac60a2f8bbdb779d2fb7baca091e53370b22adf8a9a5ec2fc9dbe16ae43ee9f3676d8e0b03b8e995153022136342fb1db65cbfc6cc72eb4a3
6
+ metadata.gz: 5b3a7534a6668e92a89ac8c605502017e5bbafe4fa930a856bfc5e6c037bae2eedcd7fe83bbc4c92482bdfd83df1ffb9aa536d656f76b55dbe7912e1d0d3d27d
7
+ data.tar.gz: 3d79c608d88e060845516c5424bd1374d04769014acec7961a701ca64de60274c8ce061cb0d6e080776c29f0476556e1710d879345ed680ce90801fcf19a0d20
@@ -0,0 +1,2 @@
1
+ language: ruby
2
+ script: "bundle exec rake test"
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ # gem "aster", path: "/Users/sam/Documents/Projects/aster"
3
4
  # Specify your gem's dependencies in asteroid.gemspec
4
5
  gemspec
data/README.md CHANGED
@@ -1,9 +1,50 @@
1
1
  # Asteroid
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/asteroid.svg)](http://badge.fury.io/rb/asteroid)
3
4
 
4
- gem install asteroid
5
+ Asteroid is a server management framework built in Ruby. It is heavily inspired by [Fucking Shell Scripts](http://fuckingshellscripts.org).
6
+
7
+ ### Creating a new Project
8
+
9
+ ```sh
10
+ gem install asteroid
11
+ asteroid new <project_name>
12
+ ```
13
+
14
+ ### Things you need to edit
15
+
16
+ * `secrets/providers.rb` contains the file that loads providers
17
+ * `secrets/secrets.yml` is a place to store secrets used elsewhere
18
+
19
+ ### Create a new Server
20
+
21
+ To create a server, create a `.yml` file in `asteroid/servers`. Create one named `web.yml` that looks like this:
22
+
23
+ ```yaml
24
+ name: web
25
+
26
+ instance_options:
27
+ size_id: 61 # DigitalOcean 1gb
28
+ region_id: 12 # DigitalOcean NYC2
29
+ ssh_key_ids: [1123232]
30
+
31
+ commands:
32
+ after-create:
33
+ - configure
34
+
35
+ configure:
36
+ - run apt-get upgrade
37
+
38
+ ```
39
+
40
+ ### To create an instance
41
+
42
+ Run this in your project root
43
+
44
+ ```sh
45
+ asteroid server create web
46
+ ```
47
+
48
+ If everything is configured you should have a new server in the cloud.
5
49
 
6
- asteroid new <project>
7
50
 
8
- # creating new directory
9
- #
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require "bundler/gem_tasks"
4
4
  task :default => :test
5
5
 
6
6
  require 'rake/testtask'
7
+
7
8
  Rake::TestTask.new(:test) do |test|
8
9
  test.libs << 'lib' << 'test' << '.'
9
10
  test.pattern = 'test/**/test_*.rb'
@@ -29,5 +29,4 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "rake"
30
30
  spec.add_development_dependency "pry"
31
31
  spec.add_development_dependency "minitest"
32
- spec.add_development_dependency "autotest"
33
32
  end
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/asteroid'
3
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib/')
4
+
5
+ require 'asteroid'
4
6
  require 'asteroid/application'
5
7
 
6
8
  boot_file = File.expand_path('./config/asteroid.rb')
@@ -8,7 +10,7 @@ if File.exists?(boot_file)
8
10
  require boot_file
9
11
 
10
12
  # Existing Application
11
- Asteroid::Application.start ARGV
13
+ Asteroid::Application::CLI.start ARGV
12
14
 
13
15
  else
14
16
  # new application
@@ -6,16 +6,17 @@ require 'yaml'
6
6
  require 'digitalocean'
7
7
  require 'aster'
8
8
 
9
-
10
- require_relative './asteroid/version.rb'
11
- require_relative './asteroid/provider.rb'
12
- require_relative './asteroid/config.rb'
13
- require_relative './asteroid/script.rb'
14
- require_relative './asteroid/config_file.rb'
15
- require_relative './asteroid/server.rb'
16
- require_relative './asteroid/ssh_key.rb'
17
- require_relative './asteroid/instance.rb'
18
- require_relative './asteroid/template.rb'
9
+ require 'asteroid/version'
10
+ require 'asteroid/version.rb'
11
+ require 'asteroid/provider.rb'
12
+ require 'asteroid/config.rb'
13
+ require 'asteroid/file_reference.rb'
14
+ require 'asteroid/script.rb'
15
+ require 'asteroid/server.rb'
16
+ require 'asteroid/ssh_key.rb'
17
+ require 'asteroid/key_reference.rb'
18
+ require 'asteroid/instance.rb'
19
+ require 'asteroid/template.rb'
19
20
 
20
21
  module Asteroid
21
22
  end
@@ -1,19 +1,73 @@
1
1
  require 'thor'
2
+ require 'thor/group'
2
3
 
3
4
  require 'asteroid/generator'
4
5
 
5
6
  module Asteroid
6
7
 
7
- class Application < Thor
8
- desc "instances [type]", "create a asteroid application at NAME"
9
- option :type
10
- def instances()
11
- i = Instance.all
12
- binding.pry
8
+ module Application
13
9
 
10
+ class Instance < Thor
11
+ desc "list", "create a asteroid application at NAME"
12
+ def list()
13
+ instances = Asteroid::Instance.all
14
+ instances.each do |instance|
15
+ puts [instance.id, instance.name, instance.server.provider.type].join("\t")
16
+ end
17
+ end
18
+
19
+ desc "ssh [instance-id]", "run the astroid command"
20
+ def ssh(i)
21
+ end
22
+
23
+ desc "destroy COMMAND", "destroy the instance"
24
+ option :instance
25
+ def destroy(instance_id, *rest)
26
+ instance = Asteroid::Instance.find instance_id
27
+ instance.destroy
28
+ end
29
+
30
+ desc "eval COMMAND", "run the astroid command"
31
+ option :instance
32
+ option :server, banner: '<server>'
33
+ def eval(instance_id, *rest)
34
+ instance = Asteroid::Instance.find instance_id
35
+ instance.eval_command rest.join(' ')
36
+ end
37
+ end
38
+
39
+ class Server < Thor
40
+ desc "list", "list server configs"
41
+ def list
42
+ servers = Asteroid::Server.all
43
+ servers.each do |server|
44
+ puts [server.name, server.provider.type].join("\t")
45
+ end
46
+ end
47
+
48
+ desc "create TYPE", "create an instance of a server"
49
+ def create(name)
50
+ server = Asteroid::Server.named name
51
+ if server
52
+ server.create_instance!
53
+ else
54
+ puts "Unknown server named #{name}"
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ class CLI < Thor
61
+ desc "instance SUBCOMMAND", "test in CLI"
62
+ subcommand "instance", Instance
63
+
64
+ desc "server SUBCOMMAND", "test in CLI"
65
+ subcommand "server", Server
14
66
  end
67
+
15
68
  end
16
69
 
70
+
17
71
  class NewApplication < Thor
18
72
 
19
73
  desc "new NAME", "create a asteroid application at NAME"
@@ -25,7 +79,6 @@ module Asteroid
25
79
  generator.generate!
26
80
 
27
81
  #puts "from: #{options[:from]}" if options[:from]
28
- binding.pry
29
82
  end
30
83
 
31
84
  end
@@ -1,12 +1,5 @@
1
1
  module Asteroid
2
2
 
3
- def self.initialize!
4
- if File.exists?(Config.initializer)
5
- eval File.read(Config.initializer)
6
- else
7
- puts "No initializer"
8
- end
9
- end
10
3
 
11
4
  def self.root=(root)
12
5
  @root = root
@@ -20,6 +13,28 @@ module Asteroid
20
13
 
21
14
  class << self
22
15
 
16
+ def boot!
17
+ if File.exists? self.secret_config_file
18
+ @secrets = YAML::load_file self.secret_config_file || {}
19
+ else
20
+ @secrets = {}
21
+ end
22
+
23
+ # Load secret provider definition file
24
+ if File.exists?(Config.secret_provider_file)
25
+ eval File.read(Config.secret_provider_file)
26
+ end
27
+
28
+ # Set search paths
29
+ Asteroid::FileReference.search_paths << Config.file_dir
30
+ Asteroid::FileReference.search_paths << Config.secret_file_dir
31
+
32
+ Asteroid::ScriptReference.search_paths << Config.script_dir
33
+ Asteroid::ScriptReference.search_paths << Config.secret_script_dir
34
+
35
+ Asteroid::KeyReference.search_paths << Config.secret_key_dir
36
+ end
37
+
23
38
  def configure(root, options = {}, &block)
24
39
  options = default_config(root)
25
40
  options.merge! options
@@ -29,18 +44,17 @@ module Asteroid
29
44
 
30
45
  yield self if block_given?
31
46
 
32
- if File.exists? self.secret_config_file
33
- @secrets = YAML::load_file self.secret_config_file || {}
34
- else
35
- @secrets = {}
36
- end
37
-
47
+ boot!
38
48
  end
39
49
 
40
50
  def secret
41
51
  @secrets
42
52
  end
43
53
 
54
+ def template_engines
55
+ @template_engines ||= {}
56
+ end
57
+
44
58
  attr_accessor :asteroid_dir
45
59
  attr_accessor :script_dir
46
60
  attr_accessor :file_dir
@@ -59,7 +73,7 @@ module Asteroid
59
73
  def default_config(root)
60
74
  asteroid_dir = File.join(root, '/asteroid')
61
75
  config_dir = File.join(root, '/config')
62
- secret_dir = File.join(root, '/sercrets')
76
+ secret_dir = File.join(root, '/secrets')
63
77
 
64
78
  {
65
79
  asteroid_dir: asteroid_dir,
@@ -0,0 +1,102 @@
1
+ require 'tempfile'
2
+ require 'pathname'
3
+
4
+ module Asteroid
5
+ class FileReference
6
+
7
+ class << self
8
+ def search_paths
9
+ @search_paths ||= []
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def path_is_absolute?(path)
16
+ Pathname.new(path).absolute?
17
+ end
18
+
19
+ public
20
+
21
+ attr_accessor :data
22
+
23
+ def initialize(fname)
24
+ if path_is_absolute?(fname)
25
+ @filename = fname
26
+ else
27
+ # Scan search paths looking for exact match
28
+ self.class.search_paths.each do |search|
29
+ break unless @filename.nil?
30
+ proposed_filename = File.join(search, fname)
31
+ if File.exists?(proposed_filename)
32
+ @filename = proposed_filename
33
+ end
34
+ end
35
+
36
+ # Scan search paths looking for partial match
37
+ self.class.search_paths.each do |search|
38
+ break unless @filename.nil?
39
+ glob = File.join(search, fname + "*")
40
+ matches = Dir[glob]
41
+ if matches.size == 1
42
+ @filename = matches.first
43
+ elsif matches.size > 1
44
+ raise "Ambiguous filename #{fname}"
45
+ end
46
+ end
47
+ end
48
+
49
+ if @filename.nil?
50
+ raise "Could not find file #{fname}"
51
+ end
52
+ end
53
+
54
+ def name
55
+ File.basename @filename
56
+ end
57
+
58
+ def type
59
+ name.split('.').last.to_sym
60
+ end
61
+
62
+ def exists?
63
+ # should always be yes
64
+ File.exists?(@filename)
65
+ end
66
+
67
+ def template?
68
+ last = @filename.split('.').last
69
+ if last
70
+ Asteroid::Config.template_engines.keys.include?(last.to_sym)
71
+ else
72
+ false
73
+ end
74
+ end
75
+
76
+ def filename
77
+ @filename
78
+ end
79
+
80
+ def rendered_filename
81
+ if template?
82
+ @rendered_filename ||= begin
83
+ file = Tempfile.new('config')
84
+ file.write render
85
+ file.rewind
86
+ file.path
87
+ end
88
+ else
89
+ filename
90
+ end
91
+ end
92
+
93
+ def render(extra = nil)
94
+ template_data = read
95
+ rendered_template = Template.new(:erb).render(
96
+ template_data,
97
+ data.merge(extra)
98
+ )
99
+ end
100
+
101
+ end
102
+ end
@@ -53,10 +53,6 @@ module Asteroid
53
53
 
54
54
  mkdir c[:secret_key_dir]
55
55
  touch File.join(c[:secret_key_dir], '.keep')
56
-
57
-
58
- binding.pry
59
-
60
56
  end
61
57
 
62
58
 
@@ -24,21 +24,41 @@ module Asteroid
24
24
 
25
25
  attr_reader :server,
26
26
  :provider,
27
- :type
27
+ :type,
28
+ :id,
29
+ :name,
30
+ :ip_address
28
31
 
29
32
 
30
33
  def initialize(options = {})
31
- @provider = options.delete :provider
34
+ options = options.dup
35
+
36
+ o = options.dup
37
+
32
38
  @server = options.delete :server
33
39
  @type = options.delete :type
40
+ @id = options.delete :id
41
+ @name = options.delete :name
42
+ @ip_address = options.delete :ip_address
34
43
 
35
- @attributes = options
44
+ if @name && @type.nil?
45
+ @type = name.split('-').first.to_sym
46
+ end
47
+
48
+ if @server.nil? && @type.nil?
49
+ raise "Instance must have a server type :type attribute"
50
+ elsif @server.nil?
51
+ @server = Server.named @type
52
+ end
53
+
54
+ if @provider
36
55
 
37
- # Validate Attributes
38
- require_attribute :name
39
- require_attribute :id
56
+ end
57
+
58
+ @attributes = options
40
59
 
41
- provider.required_instance_attributes.each do |att|
60
+
61
+ server.provider.required_instance_attributes.each do |att|
42
62
  require_attribute att
43
63
  end
44
64
 
@@ -84,7 +104,7 @@ module Asteroid
84
104
  end
85
105
 
86
106
  def self.find(id)
87
- all.select{|i| i.id == id}.first
107
+ all.select{|i| i.id == id || i.id.to_s == id.to_s}.first
88
108
  end
89
109
 
90
110
  def env
@@ -98,7 +118,7 @@ module Asteroid
98
118
  end
99
119
 
100
120
  def destroy
101
- @provider.destroy_instance self
121
+ server.provider.destroy_instance self
102
122
  end
103
123
 
104
124
  private