uhlenbrock-slicehost-tools 0.0.3

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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008 Cameron Cox <cameroncox@gmail.com>
4
+ "SliceHost" and "slice" are trademarks of Slicehost, LLC.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,40 @@
1
+ # slicehost-tools
2
+
3
+ Manage Slicehost Slices and DNS records/zones from the command line.
4
+
5
+ ## WARNING
6
+
7
+ I am not responsible if this eats your data, destroys your life, and sleeps with your wife. YOU HAVE BEEN WARNED.
8
+
9
+ ## Installation
10
+
11
+ gem sources -a http://gems.github.com
12
+
13
+ sudo gem install wycats-thor
14
+ sudo gem install uhlenbrock-slicehost-tools
15
+
16
+ ## Usage
17
+
18
+ slicehost-dns
19
+
20
+ add [DOMAIN] [IP] add a domain for the given ip
21
+ list lists all zones and their associated records
22
+ delete [DOMAIN] removes a domain
23
+ apikey [APIKEY] set your Slicehost API Key and save it to ~/.slicehost-tools
24
+ help [TASK] describe available tasks or one specific task
25
+
26
+ slicehost-slice
27
+
28
+ add [SLICE NAME] [--force] add a new slice
29
+ delete [SLICE] delete a slice
30
+ list list slices
31
+ hard_reboot [SLICE] perform a hard reboot
32
+ soft_reboot [SLICE] perform a soft reboot
33
+ apikey [APIKEY] set your Slicehost API Key and save it to ~/.slicehost-tools
34
+ help [TASK] describe available tasks or one specific task
35
+
36
+
37
+ ## TODO
38
+
39
+ [DONE] Finish up the slice tool
40
+ Multiple Slicehost accounts? (not likely, but an idea)
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/gempackagetask'
4
+
5
+ gem_spec = Gem::Specification.new do |s|
6
+ s.name = %q{slicehost-tools}
7
+ s.version = "0.0.3"
8
+
9
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Cameron Cox"]
13
+ s.date = %q{2008-07-1}
14
+ s.summary = %q{tools utilizing the slicehost api}
15
+ s.email = %q{cameroncox@gmail.com}
16
+ s.executables = ["slicehost-dns", "slicehost-slice"]
17
+ s.extra_rdoc_files = ["README.markdown", "LICENSE"]
18
+ s.files = Dir['**/**'].reject!{ |f| f =~ /pkg/i }
19
+ s.has_rdoc = false
20
+ s.homepage = %q{http://github.com/cameroncox/slicehost-tools/}
21
+ s.require_paths = ["lib"]
22
+ s.rubygems_version = %q{1.1.1}
23
+ s.add_dependency("wycats-thor", ">= 0.9.2")
24
+ end
25
+
26
+ Rake::GemPackageTask.new(gem_spec) do |p|
27
+ p.gem_spec = gem_spec
28
+ p.need_tar = true
29
+ p.need_zip = true
30
+ end
data/bin/slicehost-dns ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + "/../lib/slicehost-tools"
3
+ require :"slicehost-tools" / :tools / :dns
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + "/../lib/slicehost-tools"
3
+ require :"slicehost-tools" / :tools / :slice
@@ -0,0 +1,16 @@
1
+ %w( rubygems thor activeresource fileutils ).each do |dep|
2
+ begin
3
+ require dep
4
+ rescue LoadError
5
+ abort "#{dep} is required for the slicehost-tools suite to run."
6
+ end
7
+ end
8
+
9
+ # add the current directory to the search path...
10
+ $: << File.expand_path( File.dirname(__FILE__) )
11
+
12
+ require 'slicehost-tools/extlib'
13
+ require :"slicehost-tools" / :resources
14
+ require :"slicehost-tools" / :tools
15
+
16
+ trap('INT') { exit }
@@ -0,0 +1,2 @@
1
+ require File.join( File.expand_path(File.dirname(__FILE__)), "extlib", "symbol" )
2
+ require File.join( File.expand_path(File.dirname(__FILE__)), "extlib", "string" )
@@ -0,0 +1,5 @@
1
+ class String
2
+ def /(path)
3
+ File.join(self.to_s, path.to_s)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Symbol
2
+ def /(path)
3
+ File.join(self.to_s, path.to_s)
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+
2
+ if File.exists? ENV['HOME'] / :".slicehost-tools"
3
+ load ENV['HOME'] / :".slicehost-tools"
4
+ else
5
+ require :"slicehost-tools" / :tools
6
+ Tools::Default.start(['apikey'])
7
+ exit
8
+ end
9
+
10
+ module Resources
11
+ class Base < ActiveResource::Base
12
+ self.site = "http://#{SlicehostSecretKey}@api.slicehost.com" if defined?(SlicehostSecretKey)
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module Resources
2
+ class Zone < Base
3
+
4
+ def records(reload = false)
5
+ @records = nil if reload
6
+ @records ||= Record.find(:all, :params => { :zone_id => self.id })
7
+ end
8
+
9
+ class << self
10
+ def find_by_origin(origin)
11
+ find(:first, :params => { :origin => "#{origin}." })
12
+ end
13
+ end
14
+ end
15
+
16
+ class Record < Base
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module Resources
2
+ class Slice < Base
3
+ class << self
4
+ def find_by_name(name)
5
+ find(:first, :params => { :name => name })
6
+ end
7
+ end
8
+ end
9
+
10
+ class Flavor < Base
11
+ def to_s; self.name;
12
+ end
13
+ end
14
+
15
+ class Image < Base
16
+ def to_s; self.name;
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ module Tools
2
+
3
+ class Default < Thor
4
+
5
+ desc "apikey [APIKEY]",
6
+ "set your Slicehost API Key and save it to ~/.slicehost-tools"
7
+ def apikey(apikey = nil)
8
+ @write_file = false
9
+ unless File.exists? ENV['HOME'] / '.slicehost-tools'
10
+ @write_file = true
11
+ else
12
+ # it does exist, ask.
13
+ print "This will replace the stored key, are you sure? [y/N] "
14
+ case STDIN.gets.chomp
15
+ when /y/i
16
+ @write_file = true
17
+ end
18
+ end
19
+
20
+ # ask for api key if none is given
21
+ if apikey.nil? && @write_file
22
+ puts "Please enter your API key since you did not provide one: "
23
+ apikey = STDIN.gets.chomp
24
+ end
25
+
26
+ # write the api key to file
27
+ if @write_file
28
+ File.open( ENV['HOME'] / '.slicehost-tools', File::RDWR|File::TRUNC|File::CREAT, 0664 ) do |f|
29
+ f.puts "SlicehostSecretKey = '#{apikey}'"
30
+ f.close
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,71 @@
1
+ require :"slicehost-tools" / :resources / :dns
2
+ module Tools
3
+ class DNS < Default
4
+
5
+ map "-L" => :list
6
+
7
+ desc "add [DOMAIN] [IP]", "add a domain for the given ip"
8
+ def add(domain = nil, ip = nil)
9
+ unless domain
10
+ puts "Please give a domain to add:"
11
+ domain = STDIN.gets.chomp
12
+ end
13
+
14
+ unless ip
15
+ puts "Please give the IP to use for this domain"
16
+ ip = STDIN.gets.chomp
17
+ end
18
+
19
+ zone = Resources::Zone.new( :origin => "#{domain}.", :ttl => 3660, :active => "Y" )
20
+
21
+ if zone.save
22
+
23
+ Resources::Record.new( :record_type => 'NS', :zone_id => zone.id, :name => "#{domain}.", :data => "ns1.slicehost.net" ).save
24
+ Resources::Record.new( :record_type => 'NS', :zone_id => zone.id, :name => "#{domain}.", :data => "ns2.slicehost.net" ).save
25
+ Resources::Record.new( :record_type => 'NS', :zone_id => zone.id, :name => "#{domain}.", :data => "ns3.slicehost.net" ).save
26
+ Resources::Record.new( :record_type => 'A', :zone_id => zone.id, :name => "#{domain}.", :data => "#{ip}" ).save
27
+ Resources::Record.new( :record_type => 'CNAME', :zone_id => zone.id, :name => "www", :data => "#{domain}.").save
28
+ Resources::Record.new( :record_type => 'CNAME', :zone_id => zone.id, :name => "ftp", :data => "#{domain}.").save
29
+
30
+ puts "#{domain} added successfully."
31
+ else
32
+ puts "\n#{domain} could not be added."
33
+ puts zone.errors.full_messages.to_yaml
34
+ end
35
+ end
36
+
37
+ desc "list", "lists all zones and their associated records"
38
+ def list(domain = nil)
39
+ list_params = { :origin => "#{domain}." } unless domain.nil?
40
+ list_params ||= {}
41
+ Resources::Zone.find(:all, :params => list_params).each do |zone|
42
+ puts "+ #{zone.origin}"
43
+ zone.records.each do |record|
44
+ puts [' -', "[#{record.record_type}]".ljust(7, ' '), "#{record.name}"].join(' ')
45
+ end
46
+ end
47
+ end
48
+
49
+ desc "delete [DOMAIN]", "removes a domain"
50
+ def delete(domain = nil)
51
+ abort "You must give a domain" if domain.nil?
52
+
53
+ puts "Type the phrase \"I am sure\" to remove this zone"
54
+ @sure = false
55
+ case STDIN.gets.chomp
56
+ when "I am sure"
57
+ @sure = true
58
+ end
59
+
60
+ if @sure && domain
61
+ Resources::Zone.find_by_origin(domain).destroy
62
+ puts "#{domain} is no more."
63
+ else
64
+ puts "aborting"
65
+ end
66
+ end
67
+
68
+ # init Thor
69
+ start
70
+ end
71
+ end
@@ -0,0 +1,119 @@
1
+ require :"slicehost-tools" / :resources / :slice
2
+ module Tools
3
+ class Slice < Default
4
+
5
+ map "-L" => :list
6
+
7
+ desc "add [SLICE NAME]", "add a new slice"
8
+ method_options :force => :boolean
9
+ def add(slice_name, opts)
10
+ images = Resources::Image.find(:all)
11
+ flavors = Resources::Flavor.find(:all)
12
+
13
+ puts "Available Images: "
14
+ image_id = select_image_from(images)
15
+
16
+ puts "Available Flavors: "
17
+ flavor_id = select_flavor_from(flavors)
18
+
19
+ @add = false
20
+ # confirm you want to do this, it does cost money
21
+ unless opts[:force]
22
+ print "Are you sure you want do this? [y/N]: "
23
+ case STDIN.gets.chomp
24
+ when /y/i
25
+ @add = true
26
+ end
27
+ end
28
+
29
+ if @add
30
+ slice = Resources::Slice.new(:name => slice_name, :flavor_id => flavor_id, :image_id => image_id)
31
+ slice.save
32
+ end
33
+
34
+ end
35
+
36
+ desc "delete [SLICE]", "delete a slice"
37
+ def delete(slice_name = nil)
38
+ slice_name = select_slice.name if slice_name.nil?
39
+
40
+ @abort = true
41
+ slice = Resources::Slice.find_by_name(slice_name)
42
+ puts "Please type 'I understand this is not undoable' to proceed: "
43
+ case STDIN.gets.chomp
44
+ when "I understand this is not undoable"
45
+ @abort = false
46
+ end
47
+
48
+ unless @abort
49
+ puts "You have 5 seconds to change your mind (CTRL+C)"
50
+ sleep 5
51
+ puts "Say goodnight gracie."
52
+ slice.destroy
53
+ sleep 3
54
+ puts "Goodnight gracie."
55
+ else
56
+ puts "Your slice has not been nuked. (I hope)"
57
+ end
58
+
59
+ end
60
+
61
+ desc "list", "list slices"
62
+ def list
63
+ Resources::Slice.find(:all).each do |slice|
64
+ puts "+ #{slice.name} (#{slice.ip_address})"
65
+ end
66
+ end
67
+
68
+ desc "hard_reboot [SLICE]", "perform a hard reboot"
69
+ def hard_reboot(slice_name = nil)
70
+ slice_name = select_slice.name if slice_name.nil?
71
+
72
+ puts "(hard) rebooting #{slice_name}"
73
+ reboot(:hard_reboot, slice_name)
74
+ end
75
+
76
+ desc "soft_reboot [SLICE]", "perform a soft reboot"
77
+ def soft_reboot(slice_name = nil)
78
+ slice_name = select_slice.name if slice_name.nil?
79
+
80
+ puts "(soft) rebooting #{slice_name}"
81
+ reboot(:reboot, slice_name)
82
+ end
83
+
84
+
85
+ protected
86
+
87
+ def select_slice
88
+ slices = Resources::Slice.find(:all)
89
+ slices.each_index { |i| puts "[#{i}] #{slices[i].name}" }
90
+ print "Select a Slice by #: "
91
+ input = STDIN.gets.chomp.to_i
92
+ slices[input]
93
+ end
94
+
95
+ def select_image_from(images)
96
+ images.each_index { |i| puts "[#{i}] #{images[i].name}" }
97
+ print "Select an Image by #: "
98
+ input = STDIN.gets.chomp.to_i
99
+ images[input].id
100
+ end
101
+
102
+ def select_flavor_from(flavors)
103
+ flavors.each_index { |i| puts "[#{i}] #{flavors[i].name} (#{flavors[i].ram}mb) ($#{flavors[i].price}/month)" }
104
+ print "Select an Image by #: "
105
+ input = STDIN.gets.chomp.to_i
106
+ flavors[input].id
107
+ end
108
+
109
+ def reboot(type, slice_name)
110
+ slice = Resources::Slice.find_by_name(slice_name)
111
+ slice.put(type)
112
+ end
113
+
114
+ public
115
+
116
+ # init thor
117
+ start
118
+ end
119
+ end
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{slicehost-tools}
3
+ s.version = "0.0.3"
4
+
5
+ s.specification_version = 2 if s.respond_to? :specification_version=
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Cameron Cox"]
9
+ s.date = %q{2008-07-1}
10
+ s.summary = %q{tools utilizing the slicehost api}
11
+ s.email = %q{cameroncox@gmail.com}
12
+ s.executables = ["slicehost-dns", "slicehost-slice"]
13
+ s.extra_rdoc_files = ["README.markdown", "LICENSE"]
14
+ s.files = ["bin", "bin/slicehost-dns", "bin/slicehost-slice", "lib", "lib/slicehost-tools", "lib/slicehost-tools/extlib", "lib/slicehost-tools/extlib/string.rb", "lib/slicehost-tools/extlib/symbol.rb", "lib/slicehost-tools/extlib.rb", "lib/slicehost-tools/resources", "lib/slicehost-tools/resources/dns.rb", "lib/slicehost-tools/resources/slice.rb", "lib/slicehost-tools/resources.rb", "lib/slicehost-tools/tools", "lib/slicehost-tools/tools/dns.rb", "lib/slicehost-tools/tools/slice.rb", "lib/slicehost-tools/tools.rb", "lib/slicehost-tools.rb", "LICENSE", "Rakefile", "README.markdown", "slicehost-tools.gemspec"]
15
+ # s.has_rdoc = false
16
+ s.homepage = %q{http://github.com/cameroncox/slicehost-tools/}
17
+ s.require_paths = ["lib"]
18
+ s.rubygems_version = %q{1.1.1}
19
+ s.add_dependency("wycats-thor", ">= 0.9.2")
20
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uhlenbrock-slicehost-tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Cox
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-01 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: wycats-thor
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.2
23
+ version:
24
+ description:
25
+ email: cameroncox@gmail.com
26
+ executables:
27
+ - slicehost-dns
28
+ - slicehost-slice
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.markdown
33
+ - LICENSE
34
+ files:
35
+ - bin
36
+ - bin/slicehost-dns
37
+ - bin/slicehost-slice
38
+ - lib
39
+ - lib/slicehost-tools
40
+ - lib/slicehost-tools/extlib
41
+ - lib/slicehost-tools/extlib/string.rb
42
+ - lib/slicehost-tools/extlib/symbol.rb
43
+ - lib/slicehost-tools/extlib.rb
44
+ - lib/slicehost-tools/resources
45
+ - lib/slicehost-tools/resources/dns.rb
46
+ - lib/slicehost-tools/resources/slice.rb
47
+ - lib/slicehost-tools/resources.rb
48
+ - lib/slicehost-tools/tools
49
+ - lib/slicehost-tools/tools/dns.rb
50
+ - lib/slicehost-tools/tools/slice.rb
51
+ - lib/slicehost-tools/tools.rb
52
+ - lib/slicehost-tools.rb
53
+ - LICENSE
54
+ - Rakefile
55
+ - README.markdown
56
+ - slicehost-tools.gemspec
57
+ has_rdoc: false
58
+ homepage: http://github.com/cameroncox/slicehost-tools/
59
+ post_install_message:
60
+ rdoc_options: []
61
+
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ requirements: []
77
+
78
+ rubyforge_project:
79
+ rubygems_version: 1.2.0
80
+ signing_key:
81
+ specification_version: 2
82
+ summary: tools utilizing the slicehost api
83
+ test_files: []
84
+