nephele 0.1.0

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