nephele 0.1.0

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.
data/.autotest ADDED
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'autotest/growl'
3
+ require 'autotest/fsevent'
4
+ require 'autotest/restart'
5
+ #require 'redgreen/autotest'
6
+ rescue LoadError
7
+ end
8
+
9
+ Autotest.add_hook :initialize do |autotest|
10
+ %w{.git .svn .hg .DS_Store ._* vendor tmp log doc}.each do |exception|
11
+ autotest.add_exception(exception)
12
+ end
13
+ end
14
+
15
+ # Override autotest default magic to rerun all tests every time a
16
+ # change is detected on the file system.
17
+ class Autotest
18
+ def get_to_green
19
+ begin
20
+ rerun_all_tests
21
+ wait_for_changes unless all_good
22
+ end until all_good
23
+ end
24
+ end
25
+
26
+ Autotest::Growl::show_modified_files = true
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source :rubygems
2
+
3
+ gem 'rake'
4
+ gem 'cloudservers', :tag => 'v0.4.0'
5
+ gem 'awesome_print'
6
+ gem 'optitron'
7
+
8
+ group :development do
9
+ gem 'wirble'
10
+ gem 'shoulda'
11
+ gem 'mocha'
12
+ gem 'autotest'
13
+ gem 'autotest-fsevent'
14
+ gem 'autotest-growl'
15
+ gem 'bundler'
16
+ gem 'jeweler', '~>1.5.2'
17
+ end
18
+
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2009 - 2010:
4
+
5
+ * {Jeffrey O'Dell}[http://github.com/jodell/nephele]
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ 'Software'), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
+ S
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ Nephele
2
+ ========
3
+
4
+ Nephele is a thin abstraction layer around major cloud service API's.
5
+
6
+ Its main goals are simplicity and the unification of common tasks for the sake of working with a set of services.
7
+
8
+ Planned support:
9
+
10
+ * Rackspace
11
+ * EC2
12
+
13
+ Other Interesting Projects
14
+ --------------------------
15
+ * Fog - https://github.com/geemus/fog
16
+ * EC2 DSL - https://github.com/auser/poolparty
data/Rakefile ADDED
@@ -0,0 +1,126 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'bundler'
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ require 'rake'
13
+ require 'rake/testtask'
14
+ require 'json'
15
+ require 'jeweler'
16
+ require 'ap'
17
+ require 'irb'
18
+ $: << File.expand_path(File.dirname(__FILE__) + '/lib')
19
+ require 'nephele'
20
+
21
+ Jeweler::Tasks.new do |gem|
22
+ gem.name = "nephele"
23
+ gem.summary = %-Light administration utility for popular cloud services-
24
+ gem.description = %-Light administration utility for popular cloud services-
25
+ gem.email = 'jeffrey.odell@gmail.com'
26
+ gem.authors = ["Jeffrey O'Dell"]
27
+ gem.executables = ['nephele']
28
+ gem.homepage = 'https://github.com/jodell/nephele'
29
+ end
30
+
31
+ task :default => :'test:unit'
32
+
33
+ task :tags do
34
+ sh 'ctags -R *'
35
+ end
36
+
37
+ Rake::TestTask.new('test:unit') do |t|
38
+ t.libs << 'test'
39
+ t.pattern = 'test/tc_*'
40
+ t.verbose = true
41
+ end
42
+
43
+ def default
44
+ @@default ||= Nephele.new :service => :default
45
+ end
46
+
47
+ desc 'List available servers'
48
+ task :servers do
49
+ ap default.servers.map { |i| i[:name] }
50
+ end
51
+
52
+ task :list => :servers
53
+
54
+ desc 'List available images'
55
+ task :images do
56
+ ap default.images.map { |i| i[:name] }
57
+ end
58
+
59
+ desc 'List available flavors'
60
+ task :flavors do
61
+ ap default.flavors.map { |i| i[:name] }
62
+ end
63
+
64
+ desc 'Show node statuses'
65
+ task :status do
66
+ puts default.status
67
+ end
68
+
69
+ desc 'Key a host'
70
+ task :key, [:host] do |t, args|
71
+ host = args[:host] =~ /(.*)@(.*)/ ? args[:host] : "root@#{args[:host]}"
72
+ user = ENV['user'] || 'root'
73
+ home = user == 'root' ? '/root' : "~#{user}"
74
+ cmd = <<-EoC
75
+ ssh #{host} 'mkdir -p #{home}/.ssh && \
76
+ echo "#{my_default_key}" >> #{home}/.ssh/authorized_keys && \
77
+ chown -R #{user}:#{user} #{home}/.ssh'
78
+ EoC
79
+ sh cmd
80
+ end
81
+
82
+ desc 'Reset the node password (performs a reoot)'
83
+ task :password, [:node, :pass] do |t, args|
84
+ default.server_objs.find { |s| s.name == args[:node] }.update(:adminPass => args[:pass])
85
+ end
86
+
87
+ desc 'Save an image of the node'
88
+ task :save, [:node, :name] do |t, args|
89
+ default.server_objs.find { |s| s.name == args[:node] }.create_image args[:name]
90
+ end
91
+
92
+ desc "Creates a node with name, image name, flavor, optional count: `rake create[mybox,oberon,'512 server'] count=4`"
93
+ task :create, [:name, :image, :flavor] do |t, args|
94
+ (ENV['count'] || 1).to_i.times do |i|
95
+ @node = default.create \
96
+ :name => args[:name] + "#{ENV['count'] ? i + 1 : ''}",
97
+ :image => Nephele::Rackspace.image_lookup(args[:image]),
98
+ :flavor => args[:flavor],
99
+ :personality => Nephele::Rackspace::Util.personality(ENV['personality'] || :default)
100
+ end
101
+ end
102
+
103
+ JODELL_CHEF_BOOTSTRAPPER = 'https://github.com/jodell/cookbooks/raw/master/bin/bootstrap.sh'
104
+
105
+ desc 'Create a VM and run a chef bootstrapper, optional recipe, bootstrap, cookbooks args'
106
+ task :bootstrap, [:name, :image, :flavor] => :create do |t, args|
107
+ puts "Bootstrapping: #{args[:name]}..."
108
+ bootstrapper = ENV['bootstrap'] || JODELL_CHEF_BOOTSTRAPPER
109
+ alt = ENV['cookbooks']
110
+ sh %-time ssh root@#{@node.addresses[:public]} "curl #{bootstrapper} > boot && chmod +x boot && ./boot #{alt}"-
111
+ sh %{time ssh root@#{@node.addresses[:public]} "cd -P /var/chef/cookbooks && rake run[#{ENV['recipe']}]"} if ENV['recipe']
112
+ end
113
+
114
+ desc 'Destroy, bootstrap'
115
+ task :restrap, [:name, :image, :flavor] => [:destroy, :bootstrap]
116
+
117
+ desc 'Destroy a node with name `rake destroy[foo]`'
118
+ task :destroy, [:name] do |t, args|
119
+ puts "Destroying: #{args[:name]}"
120
+ default.server_objs.find { |s| s.name == args[:name] }.delete!
121
+ end
122
+
123
+ desc 'Start IRB with the relevant env'
124
+ task :console do
125
+ ARGV.clear and IRB.start
126
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/nephele ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optitron'
5
+ begin
6
+ require 'nephele'
7
+ rescue LoadError
8
+ $: << File.expand_path(File.dirname(__FILE__) + '/../lib')
9
+ require 'nephele'
10
+ end
11
+ #require 'ap'
12
+
13
+ class Nephele::Runner < Optitron::CLI
14
+ JODELL_CHEF_BOOTSTRAPPER = 'https://github.com/jodell/cookbooks/raw/master/bin/bootstrap.sh'
15
+ class_opt 'cookbooks', "optional cookbooks URI", :type => :string
16
+ class_opt 'personality', 'comma-separated tuple of contents,targetfile to be placed at startup', :type => :string
17
+ class_opt 'bootstrap', "optional bootstrapper URI, defaults to #{JODELL_CHEF_BOOTSTRAPPER}", :type => :string
18
+ class_opt 'recipe', "run this recipe after bootstrapping", :type => :string
19
+
20
+ desc 'Display a list of servers'
21
+ def list
22
+ puts service.servers.map { |i| i[:name] }
23
+ end
24
+
25
+ desc 'Display available images'
26
+ def images
27
+ puts default.images.map { |i| i[:name] }
28
+ end
29
+
30
+ desc 'List available flavors'
31
+ def flavors
32
+ puts service.flavors.map { |i| i[:name] }
33
+ end
34
+
35
+ desc 'Display server status'
36
+ def status
37
+ puts service.status
38
+ end
39
+
40
+ desc 'Change a password on given node'
41
+ def password(node_string, password_string)
42
+ service.server_objs.find { |s| s.name == node_string }.update(:adminPass => password_string)
43
+ end
44
+
45
+ desc 'Save an image of the node'
46
+ def save(node_string, savename_string)
47
+ service.server_objs.find { |s| s.name == node_string }.create_image name_string
48
+ end
49
+
50
+ desc "Creates a node with name, image name, flavor"
51
+ opt 'count', 'create foo, foo2, foo3, ...', :type => :numeric
52
+ def create(name, image, flavor)
53
+ (params['count'] || 1).to_i.times do |i|
54
+ @node = service.create \
55
+ :name => name + "#{params['count'] ? i + 1 : ''}",
56
+ :image => Nephele::Rackspace.image_lookup(image),
57
+ :flavor => flavor,
58
+ :personality => Nephele::Rackspace::Util.personality(params['personality'] || :default)
59
+ end
60
+ end
61
+
62
+ desc 'Create a VM and run a chef bootstrapper, optional recipe, bootstrap, cookbooks args'
63
+ def bootstrap(name, image, flavor)
64
+ puts "Bootstrapping: #{name}..."
65
+ create name, image, flavor
66
+ bootstrap = params['bootstrap'] || JODELL_CHEF_BOOTSTRAPPER
67
+ system %-time ssh root@#{@node.addresses[:public]} "curl #{bootstrap} > boot && chmod +x boot && ./boot #{params['cookbooks'] || ''}"-
68
+ system %{time ssh root@#{@node.addresses[:public]} "cd -P /var/chef/cookbooks && rake run[#{params['recipe']}]"} if params['recipe']
69
+ end
70
+
71
+ desc 'Destroy and bootstrap'
72
+ def restrap(name, image, flavor)
73
+ destroy name
74
+ bootstrap name, image, flavor
75
+ end
76
+
77
+ desc 'Destroy a given node'
78
+ def destroy(name_string)
79
+ if node = service.server_objs.find { |s| s.name == name_string }
80
+ puts "Destroying: #{name_string}"
81
+ node.delete!
82
+ end
83
+ end
84
+
85
+ def service
86
+ @@service ||= Nephele.new(:service => :default)
87
+ end
88
+ end
89
+
90
+ Nephele::Runner.dispatch
@@ -0,0 +1,43 @@
1
+ class Nephele::Base
2
+ attr_accessor :service, :key, :user
3
+ attr_reader :conn, :nodes
4
+
5
+ def initialize(opts = {})
6
+ @nodes = []
7
+ @key = opts[:key]
8
+ @user = opts[:user]
9
+ @service = opts[:service] || :rackspace
10
+ end
11
+
12
+ # After a verified connection, the service class should call this to
13
+ # populate the list of nodes
14
+ #
15
+ def populate!
16
+ raise 'Subclass Responsibility'
17
+ end
18
+
19
+ def conn
20
+ raise 'Subclass Responsibility'
21
+ end
22
+
23
+ def create
24
+ raise 'Subclass Responsibility'
25
+ end
26
+
27
+ def list
28
+ @nodes
29
+ end
30
+
31
+ def reset
32
+ @conn = nil
33
+ conn
34
+ end
35
+
36
+ def method_missing(meth, *args)
37
+ if conn.respond_to? meth
38
+ conn.send meth, *args
39
+ else
40
+ super
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ # Might scrap this
2
+ class Nephele::Node
3
+ attr_reader :id, :type
4
+
5
+ def initialize(opts)
6
+ if opts.is_a? Hash
7
+ @id = opts[:id]
8
+ @type = opts[:type]
9
+ else
10
+ @id = opts.id
11
+ @type = opts.class == CloudServers::Server ? :rackspace : nil
12
+ end
13
+ end
14
+
15
+ def up?
16
+ # TEMPORARY
17
+ case @type
18
+ when :rackspace
19
+ CloudServers::Server.new(@id).status == 'ACTIVE'
20
+ else
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,122 @@
1
+ class Nephele::Rackspace < Nephele::Base
2
+ attr_reader :nodes
3
+
4
+ def initialize(opts = {})
5
+ super
6
+ populate!
7
+ end
8
+
9
+ def conn
10
+ @conn ||= CloudServers::Connection.new \
11
+ :username => @user,
12
+ :api_key => @key
13
+ end
14
+
15
+ def populate!
16
+ server_objs.each { |n| register!(n) }
17
+ end
18
+
19
+ def register!(node)
20
+ @nodes << Nephele::Node.new(node)
21
+ # methods can't start with a leading digit
22
+ meth = node.name.match(/^(\d)+/) ? "_#{node.name}" : node.name
23
+ self.class.send(:define_method, meth.gsub(/\./, '_').to_sym) do
24
+ CloudServers::Server.new(conn, node.id)
25
+ end
26
+ end
27
+
28
+ def create(opts)
29
+ rack_node = conn.create_server \
30
+ :name => opts[:name],
31
+ :imageId => images_id_for_name(opts[:image]),
32
+ :flavorId => flavors_id_for_name(opts[:flavor]),
33
+ :personality => opts[:personality] || ''
34
+ puts "Server pass: #{rack_node.adminPass}, ip #{rack_node.addresses[:public]}"
35
+ register!(rack_node)
36
+ rack_node
37
+ end
38
+
39
+ def destroy(opts)
40
+ id = servers_id_for_name(opts[:name])
41
+ CloudServers::Server.new(conn, id).delete!
42
+ @nodes.delete_if { |n| n.id == id }
43
+ end
44
+
45
+ def status
46
+ header = "#{'NAME'.ljust(20)} #{'STATUS'.ljust(6)} #{'-%-'.ljust(3)} #{'Kind'.ljust(10)} Public IP\n"
47
+ info = server_objs.inject('') do |acc, s|
48
+ acc += "#{s.name.ljust(20)} #{s.status.ljust(6)} #{s.progress.to_s.ljust(3)} #{s.flavor.name.ljust(10)} #{s.addresses[:public]}\n"
49
+ end
50
+ header + info
51
+ end
52
+
53
+ def provisioning?
54
+ server_objs.any? { |s| s.status != 'ACTIVE' }
55
+ end
56
+
57
+ [:servers, :flavors, :images].each do |sym|
58
+ define_method "#{sym}_id_for_name" do |name|
59
+ _id_for_name(sym, name)
60
+ end
61
+ end
62
+
63
+ def _id_for_name(obj, name)
64
+ conn.send(obj.to_sym).find { |o| o[:name] == name }[:id]
65
+ end
66
+
67
+ def server_objs
68
+ conn.servers.inject([]) do |acc, info|
69
+ acc << CloudServers::Server.new(conn, info[:id]); acc
70
+ end
71
+ end
72
+
73
+ def image_objs
74
+ conn.images.inject([]) do |acc, info|
75
+ acc << CloudServers::Image.new(conn, info[:id]); acc
76
+ end
77
+ end
78
+
79
+ def self.image_lookup(name)
80
+ case name
81
+ when /lucid/
82
+ "Ubuntu 10.04 LTS (lucid)"
83
+ else
84
+ name
85
+ end
86
+ end
87
+ end
88
+
89
+ module Nephele::Rackspace::Util
90
+ class << self
91
+ def personality(personality)
92
+ if personality == :default
93
+ { generate_key_file => '/root/.ssh/authorized_keys',
94
+ known_hosts_file => '/root/.ssh/known_hosts' }
95
+ else
96
+ acc = {}
97
+ personality.split(',').each_slice(2) { |(k, v)| acc[k] = v }
98
+ acc
99
+ end
100
+ end
101
+
102
+ def generate_key_file
103
+ '/tmp/nephele_key_file'.tap do |file| File.open(file, 'w') { |f| f << my_default_key }; end
104
+ end
105
+
106
+ def my_default_key
107
+ File.read(File.expand_path('~/.ssh/id_dsa.pub'))
108
+ end
109
+
110
+ def known_hosts_file
111
+ '/tmp/known_hosts.nephele'.tap do |file| File.open(file, 'w') { |f| f << known_hosts }; end
112
+ end
113
+
114
+ # Github
115
+ def known_hosts
116
+ <<-EoS
117
+ |1|xLwg2PqKMACZR+6X0OH9rx66p1I=|xR01sH66lqU3PejWe+8J0EWulb0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
118
+ |1|juutFPHnSpo61K6I1Y7XnKB07yI=|u/ZYrJrAdgQ1G/cd48si2avBHTQ= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
119
+ EoS
120
+ end
121
+ end
122
+ end
data/lib/nephele.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'cloudservers'
2
+
3
+ module Nephele
4
+ SERVICES = [:rackspace, :ec2].freeze
5
+ require 'nephele/base'
6
+ require 'nephele/node'
7
+ require 'nephele/rackspace'
8
+
9
+ # Factory for service objects
10
+ def self.new(opts)
11
+ case opts[:service]
12
+ when :rackspace
13
+ Nephele::Rackspace.new :key => opts[:key], :user => opts[:user]
14
+ when :ec2
15
+ raise 'Not Implemented Yet'
16
+ when :default
17
+ Nephele::Rackspace.new default
18
+ else
19
+ raise "Unsupported service, expected one of #{SERVICES * ', '}"
20
+ end
21
+ end
22
+
23
+ def self.default
24
+ { :service => ENV['NEPHELE_SERVICE_DEFAULT'] &&
25
+ ENV['NEPHELE_SERVICE_DEFAULT'].downcase.to_sym ||
26
+ :rackspace,
27
+ :user => ENV['RACKSPACE_USER'],
28
+ :key => ENV['RACKSPACE_KEY'] }
29
+ end
30
+ end
data/nephele.gemspec ADDED
@@ -0,0 +1,91 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{nephele}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jeffrey O'Dell"]
12
+ s.date = %q{2011-04-07}
13
+ s.default_executable = %q{nephele}
14
+ s.description = %q{Light administration utility for popular cloud services}
15
+ s.email = %q{jeffrey.odell@gmail.com}
16
+ s.executables = ["nephele"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".autotest",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/nephele",
29
+ "lib/nephele.rb",
30
+ "lib/nephele/base.rb",
31
+ "lib/nephele/node.rb",
32
+ "lib/nephele/rackspace.rb",
33
+ "nephele.gemspec",
34
+ "test/helper.rb",
35
+ "test/tc_base.rb"
36
+ ]
37
+ s.homepage = %q{https://github.com/jodell/nephele}
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.6.1}
40
+ s.summary = %q{Light administration utility for popular cloud services}
41
+ s.test_files = [
42
+ "test/helper.rb",
43
+ "test/tc_base.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<rake>, [">= 0"])
51
+ s.add_runtime_dependency(%q<cloudservers>, [">= 0"])
52
+ s.add_runtime_dependency(%q<awesome_print>, [">= 0"])
53
+ s.add_runtime_dependency(%q<optitron>, [">= 0"])
54
+ s.add_development_dependency(%q<wirble>, [">= 0"])
55
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
56
+ s.add_development_dependency(%q<mocha>, [">= 0"])
57
+ s.add_development_dependency(%q<autotest>, [">= 0"])
58
+ s.add_development_dependency(%q<autotest-fsevent>, [">= 0"])
59
+ s.add_development_dependency(%q<autotest-growl>, [">= 0"])
60
+ s.add_development_dependency(%q<bundler>, [">= 0"])
61
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
62
+ else
63
+ s.add_dependency(%q<rake>, [">= 0"])
64
+ s.add_dependency(%q<cloudservers>, [">= 0"])
65
+ s.add_dependency(%q<awesome_print>, [">= 0"])
66
+ s.add_dependency(%q<optitron>, [">= 0"])
67
+ s.add_dependency(%q<wirble>, [">= 0"])
68
+ s.add_dependency(%q<shoulda>, [">= 0"])
69
+ s.add_dependency(%q<mocha>, [">= 0"])
70
+ s.add_dependency(%q<autotest>, [">= 0"])
71
+ s.add_dependency(%q<autotest-fsevent>, [">= 0"])
72
+ s.add_dependency(%q<autotest-growl>, [">= 0"])
73
+ s.add_dependency(%q<bundler>, [">= 0"])
74
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
75
+ end
76
+ else
77
+ s.add_dependency(%q<rake>, [">= 0"])
78
+ s.add_dependency(%q<cloudservers>, [">= 0"])
79
+ s.add_dependency(%q<awesome_print>, [">= 0"])
80
+ s.add_dependency(%q<optitron>, [">= 0"])
81
+ s.add_dependency(%q<wirble>, [">= 0"])
82
+ s.add_dependency(%q<shoulda>, [">= 0"])
83
+ s.add_dependency(%q<mocha>, [">= 0"])
84
+ s.add_dependency(%q<autotest>, [">= 0"])
85
+ s.add_dependency(%q<autotest-fsevent>, [">= 0"])
86
+ s.add_dependency(%q<autotest-growl>, [">= 0"])
87
+ s.add_dependency(%q<bundler>, [">= 0"])
88
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
89
+ end
90
+ end
91
+
data/test/helper.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/setup'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $: << File.expand_path(File.dirname(__FILE__) + '/lib')
7
+ require 'nephele'
data/test/tc_base.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'helper'
2
+
3
+ class TestNepheleBase < Test::Unit::TestCase
4
+ context 'sanity' do
5
+ should 'be sane' do
6
+ assert_not_nil Nephele
7
+ assert_not_nil Nephele::Base.new
8
+ end
9
+
10
+ should 'instantiate different services correctly' do
11
+ Nephele::Rackspace.any_instance.stubs(:populate!).returns(nil)
12
+ assert_kind_of Nephele::Rackspace,
13
+ Nephele.new(:service => :rackspace, :user => 'foo', :key => 'bar')
14
+ assert_raise RuntimeError do
15
+ Nephele.new(:service => :ec2, :user => 'foo', :key => 'bar')
16
+ end
17
+ assert_raise RuntimeError do
18
+ Nephele.new(:service => 'garbage', :user => 'foo', :key => 'bar')
19
+ end
20
+ end
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,251 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nephele
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Jeffrey O'Dell
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-07 00:00:00 -05:00
19
+ default_executable: nephele
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: cloudservers
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: awesome_print
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: optitron
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: wirble
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ - !ruby/object:Gem::Dependency
92
+ name: shoulda
93
+ prerelease: false
94
+ requirement: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :development
104
+ version_requirements: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: mocha
107
+ prerelease: false
108
+ requirement: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ type: :development
118
+ version_requirements: *id007
119
+ - !ruby/object:Gem::Dependency
120
+ name: autotest
121
+ prerelease: false
122
+ requirement: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ type: :development
132
+ version_requirements: *id008
133
+ - !ruby/object:Gem::Dependency
134
+ name: autotest-fsevent
135
+ prerelease: false
136
+ requirement: &id009 !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ hash: 3
142
+ segments:
143
+ - 0
144
+ version: "0"
145
+ type: :development
146
+ version_requirements: *id009
147
+ - !ruby/object:Gem::Dependency
148
+ name: autotest-growl
149
+ prerelease: false
150
+ requirement: &id010 !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ hash: 3
156
+ segments:
157
+ - 0
158
+ version: "0"
159
+ type: :development
160
+ version_requirements: *id010
161
+ - !ruby/object:Gem::Dependency
162
+ name: bundler
163
+ prerelease: false
164
+ requirement: &id011 !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ hash: 3
170
+ segments:
171
+ - 0
172
+ version: "0"
173
+ type: :development
174
+ version_requirements: *id011
175
+ - !ruby/object:Gem::Dependency
176
+ name: jeweler
177
+ prerelease: false
178
+ requirement: &id012 !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ~>
182
+ - !ruby/object:Gem::Version
183
+ hash: 7
184
+ segments:
185
+ - 1
186
+ - 5
187
+ - 2
188
+ version: 1.5.2
189
+ type: :development
190
+ version_requirements: *id012
191
+ description: Light administration utility for popular cloud services
192
+ email: jeffrey.odell@gmail.com
193
+ executables:
194
+ - nephele
195
+ extensions: []
196
+
197
+ extra_rdoc_files:
198
+ - LICENSE
199
+ - README.md
200
+ files:
201
+ - .autotest
202
+ - Gemfile
203
+ - LICENSE
204
+ - README.md
205
+ - Rakefile
206
+ - VERSION
207
+ - bin/nephele
208
+ - lib/nephele.rb
209
+ - lib/nephele/base.rb
210
+ - lib/nephele/node.rb
211
+ - lib/nephele/rackspace.rb
212
+ - nephele.gemspec
213
+ - test/helper.rb
214
+ - test/tc_base.rb
215
+ has_rdoc: true
216
+ homepage: https://github.com/jodell/nephele
217
+ licenses: []
218
+
219
+ post_install_message:
220
+ rdoc_options: []
221
+
222
+ require_paths:
223
+ - lib
224
+ required_ruby_version: !ruby/object:Gem::Requirement
225
+ none: false
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ hash: 3
230
+ segments:
231
+ - 0
232
+ version: "0"
233
+ required_rubygems_version: !ruby/object:Gem::Requirement
234
+ none: false
235
+ requirements:
236
+ - - ">="
237
+ - !ruby/object:Gem::Version
238
+ hash: 3
239
+ segments:
240
+ - 0
241
+ version: "0"
242
+ requirements: []
243
+
244
+ rubyforge_project:
245
+ rubygems_version: 1.6.1
246
+ signing_key:
247
+ specification_version: 3
248
+ summary: Light administration utility for popular cloud services
249
+ test_files:
250
+ - test/helper.rb
251
+ - test/tc_base.rb