rumm 0.0.23 → 0.0.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +11 -3
- data/app.rb +13 -0
- data/app/controllers/authentication_controller.rb +12 -11
- data/app/controllers/railsifications_controller.rb +24 -21
- data/app/controllers/servers_controller.rb +14 -4
- data/app/controllers/users_controller.rb +15 -0
- data/app/forms/servers/update_form.rb +7 -0
- data/app/forms/volumes/create_form.rb +1 -2
- data/app/help/create_container.txt +0 -1
- data/app/help/create_dbinstance.txt +1 -1
- data/app/help/create_server.txt +1 -1
- data/app/help/destroy_node_on_loadbalancer.txt +1 -1
- data/app/help/railsify_server.txt +1 -1
- data/app/help/show_attachment_on_server.txt +4 -4
- data/app/help/show_server.txt +1 -1
- data/app/help/update_server.txt +19 -0
- data/app/providers/configuration_provider.rb +118 -0
- data/app/providers/credentials_provider.rb +4 -4
- data/app/providers/login_information_provider.rb +34 -0
- data/app/providers/users_provider.rb +13 -0
- data/app/routes.rb +1 -0
- data/app/views/authentication/login.txt.erb +1 -1
- data/app/views/help/show.txt.erb +1 -1
- data/app/views/servers/update.txt.erb +1 -0
- data/app/views/users/create.txt.erb +1 -1
- data/app/views/users/destroy.txt.erb +1 -0
- data/app/views/users/show.txt.erb +1 -0
- data/lib/rumm/exceptions.rb +5 -0
- data/lib/rumm/version.rb +1 -1
- data/rumm.gemspec +1 -2
- data/spec/features/attachments_spec.rb +1 -1
- data/spec/features/configuration_spec.rb +143 -0
- data/spec/features/containers_spec.rb +1 -1
- data/spec/features/databases_spec.rb +1 -1
- data/spec/features/dbinstances_spec.rb +1 -1
- data/spec/features/files_spec.rb +1 -1
- data/spec/features/help_spec.rb +1 -1
- data/spec/features/loadbalancers_spec.rb +1 -1
- data/spec/features/login_spec.rb +47 -33
- data/spec/features/nodes_spec.rb +1 -1
- data/spec/features/servers_spec.rb +1 -1
- data/spec/features/users_spec.rb +28 -0
- data/spec/features/volumes_spec.rb +1 -1
- data/spec/fixtures/cassettes/authentication/successful-login.yml +9 -5
- data/spec/fixtures/cassettes/authentication/unsuccessful-login.yml +5 -3
- data/spec/fixtures/cassettes/users/create.yml +122 -0
- data/spec/fixtures/cassettes/users/destroy.yml +200 -0
- data/spec/fixtures/cassettes/users/show-all.yml +122 -0
- data/spec/fixtures/cassettes/users/show.yml +165 -0
- data/spec/spec_helper.rb +19 -11
- metadata +25 -19
- data/app/providers/user_provider.rb +0 -23
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YmQzNjJhOTY2NWQwYjdlZTg2ZGRlNWRjZDE1MTczMmRhMWE0ZWQyNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTQ1MTFmNzRmMzI0NDliYmFjMDYxZmY5YTMwNTllNTAyMDQ5NTZjYg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDEwOTk4MGFiMzQ1N2Y1ZmJlZTExNjU5MzAwNDBkY2VlZDY0MjY2NjBhNzhl
|
10
|
+
MzEzZDgzYzdiMTBkMDFiMTVhNTNhZjYzMDZhZmY2MzIwN2M3YTllMWYzNzU4
|
11
|
+
NGI0YjRmNGQyN2ZlY2QyZGEyZmUzYWFhYmJlNjdjMDdkZWYxYmE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjQyNWMwYzgxMjU2MmU3MDVkMTcyZWEzMWFlNjM3NGIwYjFiYTY0Mzk0Mzg2
|
14
|
+
Zjk5MzE5MjUxZDQwMzBkYjAzODkyZjkyZTZjZDU1MTcyZGE4YTJjMDdlZmM5
|
15
|
+
ODMyZmUxMGZjZWI0NTQxZGM4NDdlYTJlNmMwZmVmZGViYjM5MjE=
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
## Rumm: a tasty tool for hackers and pirates
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/rumm.png)](http://badge.fury.io/rb/rumm)
|
4
|
-
[![Build Status](https://travis-ci.org/
|
5
|
-
[![Dependency Status](https://gemnasium.com/
|
4
|
+
[![Build Status](https://travis-ci.org/rackspace/rumm.png?branch=master)](https://travis-ci.org/rackspace/rumm)
|
5
|
+
[![Dependency Status](https://gemnasium.com/rackspace/rumm.png)](https://gemnasium.com/rackspace/rumm)
|
6
6
|
|
7
7
|
|
8
8
|
Rumm is a command line interface and API to rackspace. You can use it
|
@@ -16,7 +16,9 @@ Authenticate with rackspace using your cloud credentials as follows:
|
|
16
16
|
rumm login
|
17
17
|
username: joe
|
18
18
|
password: ****
|
19
|
-
|
19
|
+
Default Region (Enter for ord):
|
20
|
+
|
21
|
+
logged in as joe, credentials written to ~/.rummrc
|
20
22
|
|
21
23
|
|
22
24
|
Now we can see the list of servers we have available:
|
@@ -35,6 +37,12 @@ For further help, including a full listing of commands, type:
|
|
35
37
|
|
36
38
|
rumm help
|
37
39
|
|
40
|
+
To access servers outside of your default region, you can prefix your rumm command with REGION=<region name>.
|
41
|
+
|
42
|
+
For example to list servers in IAD you would execute the following:
|
43
|
+
|
44
|
+
REGION=iad rumm show servers
|
45
|
+
|
38
46
|
## Further Reading
|
39
47
|
|
40
48
|
See the [official rumm website][1] for more information, including documentation.
|
data/app.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
1
|
require "mvcli/app"
|
2
2
|
require "rumm/version"
|
3
|
+
require "rumm/exceptions"
|
3
4
|
|
4
5
|
module Rumm
|
5
6
|
class App < MVCLI::App
|
6
7
|
self.root = Pathname(__FILE__).dirname
|
8
|
+
|
9
|
+
def main(argv = ARGV.dup, input = $stdin, output = $stdout, log = $stderr, env = ENV.dup)
|
10
|
+
super.tap do |code|
|
11
|
+
|
12
|
+
# HACK: print out usage information if we can't the the command
|
13
|
+
if code == MVCLI::Middleware::ExitStatus::EX_USAGE
|
14
|
+
puts "\n"
|
15
|
+
super(%w[help commands], input, output, log, env) rescue code
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
end
|
8
21
|
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
require "net/https"
|
2
2
|
require "json"
|
3
|
-
require "netrc"
|
4
3
|
require "excon"
|
5
4
|
|
6
5
|
class AuthenticationController < MVCLI::Controller
|
7
6
|
|
8
7
|
requires :user
|
8
|
+
requires :configuration
|
9
|
+
requires :login_information
|
9
10
|
|
10
11
|
def login
|
11
|
-
login_info =
|
12
|
+
login_info = login_information
|
12
13
|
username = login_info.name
|
13
14
|
password = login_info.password
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
uri = URI.parse(configuration.auth_endpoint)
|
17
|
+
connection = Excon.new(uri.to_s)
|
18
|
+
|
17
19
|
headers = {'Content-Type' => 'application/json'}
|
18
20
|
body = {auth: {passwordCredentials: {username: username, password: password}}}
|
19
21
|
|
@@ -30,16 +32,15 @@ class AuthenticationController < MVCLI::Controller
|
|
30
32
|
|
31
33
|
user_credentials = Map(JSON.parse response.body)
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
configuration.username = username
|
36
|
+
configuration.api_key = user_credentials["RAX-KSKEY:apiKeyCredentials"].apiKey
|
37
|
+
configuration.region = login_info.region
|
38
|
+
configuration.save
|
39
|
+
|
37
40
|
user_info
|
38
41
|
end
|
39
42
|
|
40
43
|
def logout
|
41
|
-
|
42
|
-
n.delete 'api.rackspace.com'
|
43
|
-
n.save
|
44
|
+
configuration.delete
|
44
45
|
end
|
45
46
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "tmpdir"
|
2
2
|
require "open3"
|
3
|
+
require "bundler"
|
3
4
|
|
4
5
|
class RailsificationsController < MVCLI::Controller
|
5
6
|
requires :compute
|
@@ -13,29 +14,31 @@ class RailsificationsController < MVCLI::Controller
|
|
13
14
|
tmpdir = Pathname(Dir.tmpdir).join 'chef_kitchen'
|
14
15
|
FileUtils.mkdir_p tmpdir
|
15
16
|
Dir.chdir tmpdir do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
17
|
+
Bundler.with_clean_env do
|
18
|
+
File.open('Gemfile', 'w') do |f|
|
19
|
+
f.puts 'source "https://rubygems.org"'
|
20
|
+
f.puts 'gem "knife-solo", ">= 0.3.0pre3"'
|
21
|
+
f.puts 'gem "berkshelf"'
|
22
|
+
end
|
23
|
+
execute "bundle install --binstubs"
|
24
|
+
execute "bin/knife solo init ."
|
25
|
+
File.open 'Berksfile', 'w' do |f|
|
26
|
+
f.puts "site :opscode"
|
27
|
+
f.puts ""
|
28
|
+
f.puts "cookbook 'runit', '>= 1.1.2'"
|
29
|
+
f.puts "cookbook 'rackbox', github: 'hayesmp/rackbox-cookbook'"
|
30
|
+
end
|
31
|
+
execute "bin/berks install --path cookbooks/"
|
32
|
+
execute "bin/knife solo prepare root@#{server.ipv4_address}"
|
33
|
+
File.open('nodes/host.json', 'w') do |f|
|
34
|
+
f.puts('{"run_list":["rackbox"],"rackbox":{"apps":{"unicorn":[{"appname":"app1","hostname":"app1"}]},"ruby":{"global_version":"2.0.0-p195","versions":["2.0.0-p195"]}}}')
|
35
|
+
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
+
FileUtils.rm_rf "#{server.ipv4_address}.json"
|
38
|
+
FileUtils.mv "nodes/host.json", "nodes/#{server.ipv4_address}.json"
|
37
39
|
|
38
|
-
|
40
|
+
execute "bin/knife solo cook root@#{server.ipv4_address}"
|
41
|
+
end
|
39
42
|
end
|
40
43
|
return server
|
41
44
|
end
|
@@ -31,6 +31,20 @@ class ServersController < MVCLI::Controller
|
|
31
31
|
return server
|
32
32
|
end
|
33
33
|
|
34
|
+
def update
|
35
|
+
template = Servers::UpdateForm
|
36
|
+
argv = MVCLI::Argv.new command.argv
|
37
|
+
form = template.new argv.options
|
38
|
+
form.validate!
|
39
|
+
|
40
|
+
unupdated_server = server
|
41
|
+
unupdated_server.name = form.name unless form.name == nil
|
42
|
+
unupdated_server.ipv4_address = form.ipv4 unless form.ipv4 == nil
|
43
|
+
unupdated_server.ipv6_address = form.ipv6 unless form.ipv6 == nil
|
44
|
+
|
45
|
+
unupdated_server.update
|
46
|
+
end
|
47
|
+
|
34
48
|
def destroy
|
35
49
|
server.tap do |s|
|
36
50
|
s.destroy
|
@@ -43,10 +57,6 @@ class ServersController < MVCLI::Controller
|
|
43
57
|
index.find {|s| s.name == params[:id]} or fail Fog::Errors::NotFound
|
44
58
|
end
|
45
59
|
|
46
|
-
def generate_name
|
47
|
-
'divine-reef'
|
48
|
-
end
|
49
|
-
|
50
60
|
def ssh
|
51
61
|
test = server
|
52
62
|
ip_address = test.ipv4_address
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class UsersController < MVCLI::Controller
|
2
2
|
requires :instances
|
3
|
+
requires :users
|
3
4
|
requires :command
|
4
5
|
|
5
6
|
def index
|
@@ -14,6 +15,20 @@ class UsersController < MVCLI::Controller
|
|
14
15
|
instance.users.create form.value
|
15
16
|
end
|
16
17
|
|
18
|
+
def show
|
19
|
+
list = users
|
20
|
+
list.instance = instance
|
21
|
+
list.all.find { |u| u.name == params[:id] } or fail Fog::Errors::NotFound
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
list = users
|
26
|
+
list.instance = instance
|
27
|
+
user = list.all.find { |u| u.name == params[:id] }
|
28
|
+
user.destroy or fail Fog::Errors::NotFound
|
29
|
+
end
|
30
|
+
|
31
|
+
|
17
32
|
private
|
18
33
|
|
19
34
|
def instance
|
@@ -5,6 +5,5 @@ class Volumes::CreateForm < MVCLI::Form
|
|
5
5
|
input :type, String, default: "SATA"
|
6
6
|
input :size, Integer, default: 100
|
7
7
|
|
8
|
-
validates(:type, "must either be SATA or SSD"){ |type| type == "SATA" or "SSD" }
|
9
|
-
validates(:size, "must be between 100 and 1024"){ |size| (100..1024) === size }
|
8
|
+
validates(:type, "must either be SATA or SSD") { |type| type == "SATA" or "SSD" }
|
10
9
|
end
|
data/app/help/create_server.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Usage:
|
2
|
-
rumm create server [--name STRING] [--image-id STRING] [--flavor-id STRING] [--ssh-private STRING] [--ssh-
|
2
|
+
rumm create server [--name STRING] [--image-id STRING] [--flavor-id STRING] [--ssh-private STRING] [--ssh-public STRING]
|
3
3
|
|
4
4
|
Options:
|
5
5
|
-n, --name STRING # Name to give the new server
|
@@ -1,14 +1,14 @@
|
|
1
1
|
Usage:
|
2
|
-
rumm show attachment on server SERVER_ID
|
2
|
+
rumm show attachment on server SERVER_ID --volume STRING
|
3
3
|
|
4
4
|
Options:
|
5
|
-
-v, --volume STRING # Name of the volume
|
5
|
+
-v, --volume STRING # Name of the attached volume
|
6
6
|
|
7
7
|
Arguments:
|
8
|
-
SERVER_ID: STRING # The name of the server
|
8
|
+
SERVER_ID: STRING # The name of the attached server
|
9
9
|
|
10
10
|
Description:
|
11
|
-
|
11
|
+
Shows details about the specified attachment.
|
12
12
|
|
13
13
|
Examples:
|
14
14
|
rumm show attachment on server superordinate-struthioniformes --volume colorful-caterpillar
|
data/app/help/show_server.txt
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
Usage:
|
2
|
+
rumm update server ID [--name STRING] [--ipv4 IPV4] [--ipv6 IPV6]
|
3
|
+
|
4
|
+
|
5
|
+
Arguments:
|
6
|
+
ID: STRING # Name of the server to update
|
7
|
+
|
8
|
+
Options:
|
9
|
+
--name: STRING # The name you want to change the server to
|
10
|
+
--ipv4: IPV4 # The ip you want to change the server to
|
11
|
+
--ipv6: IPV6 # The ip you want to change the server to
|
12
|
+
|
13
|
+
Description:
|
14
|
+
Updates the given server to the new values by updating and changing the
|
15
|
+
name, ipv4, or ipv6. It only updates the values if they're given in the
|
16
|
+
command.
|
17
|
+
|
18
|
+
Examples:
|
19
|
+
rumm update server silly-saffron --name sad-saffron
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'json'
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'fog'
|
5
|
+
|
6
|
+
class ConfigurationProvider
|
7
|
+
|
8
|
+
def value
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@config = defaults
|
14
|
+
reload
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
@config["environments"]["default"][key.to_s] rescue nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def []=(key, value)
|
22
|
+
@config["environments"]["default"][key.to_s] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
[:username, :api_key, :region].each do |sym|
|
26
|
+
class_eval <<-META
|
27
|
+
def #{sym}
|
28
|
+
self['#{sym}']
|
29
|
+
end
|
30
|
+
|
31
|
+
def #{sym}=(value)
|
32
|
+
self['#{sym}'] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
META
|
36
|
+
end
|
37
|
+
|
38
|
+
def region
|
39
|
+
region_to_str(ENV['REGION'] || self['region'])
|
40
|
+
end
|
41
|
+
|
42
|
+
def lon_region?
|
43
|
+
region == "lon"
|
44
|
+
end
|
45
|
+
|
46
|
+
def auth_endpoint
|
47
|
+
# Note: You can authenticate against any endpoint regardless of the location of your cloud account, however, to locate the proper service endpoints
|
48
|
+
# you must authenticate against the correct cloud endpoint
|
49
|
+
self.lon_region? ? Fog::Rackspace::UK_AUTH_ENDPOINT : Fog::Rackspace::US_AUTH_ENDPOINT
|
50
|
+
end
|
51
|
+
|
52
|
+
def reload
|
53
|
+
return false unless File.exists? default_path
|
54
|
+
|
55
|
+
begin
|
56
|
+
File.open default_path do |f|
|
57
|
+
h = JSON.load f
|
58
|
+
@config.merge! h
|
59
|
+
true
|
60
|
+
end
|
61
|
+
rescue => e
|
62
|
+
fail "Unable to read #{default_path} - #{e.inspect}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def save
|
67
|
+
begin
|
68
|
+
File.open default_path, 'w' do |f|
|
69
|
+
JSON.dump @config, f
|
70
|
+
true
|
71
|
+
end
|
72
|
+
rescue => e
|
73
|
+
fail "Unable to write #{default_path} - #{e.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def delete
|
79
|
+
@config = defaults
|
80
|
+
File.delete(default_path) if File.exists? default_path
|
81
|
+
true
|
82
|
+
rescue => e
|
83
|
+
fail "Unable to delete #{default_path} - #{e.inspect}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def default_path
|
87
|
+
if windows? && !cygwin?
|
88
|
+
File.join(ENV['USERPROFILE'].gsub("\\","/"), ".rummrc")
|
89
|
+
else
|
90
|
+
File.join((ENV["HOME"] || "./"), ".rummrc")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def region_to_str(str)
|
97
|
+
str ? str.to_s.downcase : nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def defaults
|
101
|
+
{ "environments" => {
|
102
|
+
"default" => {
|
103
|
+
"region" => :ord
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
# see http://stackoverflow.com/questions/4871309/what-is-the-correct-way-to-detect-if-ruby-is-running-on-windows
|
110
|
+
def windows?
|
111
|
+
RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
|
112
|
+
end
|
113
|
+
|
114
|
+
def cygwin?
|
115
|
+
RbConfig::CONFIG["host_os"] =~ /cygwin/
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|