rumm 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +46 -0
- data/Rakefile +6 -0
- data/app.rb +7 -0
- data/app/controllers/attachments_controller.rb +39 -0
- data/app/controllers/authentication_controller.rb +47 -0
- data/app/controllers/containers_controller.rb +32 -0
- data/app/controllers/databases_controller.rb +43 -0
- data/app/controllers/files_controller.rb +41 -0
- data/app/controllers/images_controller.rb +7 -0
- data/app/controllers/instances_controller.rb +34 -0
- data/app/controllers/loadbalancers_controller.rb +32 -0
- data/app/controllers/nodes_controller.rb +45 -0
- data/app/controllers/servers_controller.rb +52 -0
- data/app/controllers/volumes_controller.rb +35 -0
- data/app/forms/loadbalancers/create_form.rb +35 -0
- data/app/models/loadbalancers/node.rb +10 -0
- data/app/models/node.rb +0 -0
- data/app/providers/compute_provider.rb +15 -0
- data/app/providers/console_provider.rb +5 -0
- data/app/providers/containers_provider.rb +15 -0
- data/app/providers/credentials_provider.rb +12 -0
- data/app/providers/databases_provider.rb +13 -0
- data/app/providers/instance_provider.rb +8 -0
- data/app/providers/instances_provider.rb +13 -0
- data/app/providers/loadbalancers_provider.rb +13 -0
- data/app/providers/naming/adj.txt +20574 -0
- data/app/providers/naming/nouns.txt +50277 -0
- data/app/providers/naming_provider.rb +106 -0
- data/app/providers/nodes_provider.rb +13 -0
- data/app/providers/user_provider.rb +23 -0
- data/app/providers/volumes_provider.rb +14 -0
- data/app/routes.rb +59 -0
- data/app/views/attachments/attach.txt.erb +3 -0
- data/app/views/attachments/detach.txt.erb +3 -0
- data/app/views/attachments/index.txt.erb +7 -0
- data/app/views/attachments/show.txt.erb +5 -0
- data/app/views/authentication/login.txt.erb +2 -0
- data/app/views/authentication/logout.txt.erb +1 -0
- data/app/views/containers/create.txt.erb +5 -0
- data/app/views/containers/destroy.txt.erb +1 -0
- data/app/views/containers/index.txt.erb +7 -0
- data/app/views/containers/show.txt.erb +5 -0
- data/app/views/databases/create.txt.erb +1 -0
- data/app/views/databases/destroy.txt.erb +1 -0
- data/app/views/databases/index.txt.erb +8 -0
- data/app/views/databases/show.txt.erb +1 -0
- data/app/views/files/create.txt.erb +5 -0
- data/app/views/files/destroy.txt.erb +1 -0
- data/app/views/files/download.txt.erb +3 -0
- data/app/views/files/index.txt.erb +7 -0
- data/app/views/files/show.txt.erb +5 -0
- data/app/views/images/index.txt.erb +3 -0
- data/app/views/instances/create.txt.erb +2 -0
- data/app/views/instances/destroy.txt.erb +1 -0
- data/app/views/instances/index.txt.erb +8 -0
- data/app/views/instances/show.txt.erb +1 -0
- data/app/views/loadbalancers/create.txt.erb +1 -0
- data/app/views/loadbalancers/destroy.txt.erb +1 -0
- data/app/views/loadbalancers/index.txt.erb +8 -0
- data/app/views/loadbalancers/show.txt.erb +4 -0
- data/app/views/nodes/create.txt.erb +5 -0
- data/app/views/nodes/destroy.txt.erb +1 -0
- data/app/views/nodes/index.txt.erb +4 -0
- data/app/views/nodes/show.txt.erb +5 -0
- data/app/views/servers/create.txt.erb +2 -0
- data/app/views/servers/destroy.txt.erb +1 -0
- data/app/views/servers/index.txt.erb +8 -0
- data/app/views/servers/show.txt.erb +5 -0
- data/app/views/volumes/create.txt.erb +5 -0
- data/app/views/volumes/destroy.txt.erb +1 -0
- data/app/views/volumes/index.txt.erb +7 -0
- data/app/views/volumes/show.txt.erb +5 -0
- data/bin/rumm +5 -0
- data/lib/rumm.rb +5 -0
- data/lib/rumm/version.rb +3 -0
- data/rumm.gemspec +24 -0
- data/spec/features/login_spec.rb +29 -0
- data/spec/features/servers_spec.rb +39 -0
- data/spec/fixtures/cassettes/create-server.yml +144 -0
- data/spec/fixtures/cassettes/destroy-server.yml +159 -0
- data/spec/fixtures/cassettes/show-server.yml +214 -0
- data/spec/fixtures/cassettes/show-servers.yml +141 -0
- data/spec/spec_helper.rb +51 -0
- metadata +203 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ae99bad0d8ca431e0721494595d98aebb94bc79
|
4
|
+
data.tar.gz: 3cc05f97d08fb1c2b5b7bf42809337497d44a2a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d6d09b4f528b9dc454608cf5807dd108df226fa176cf3cdb16a54a66fb3f72b2046d91faf5e4d45914daf5fea95a79e04fb510edeaf4666a2ffb4878855117d9
|
7
|
+
data.tar.gz: daf676d8b71865cbb81a1aeb9fbcf00ba701d4b1af39154492320a6604f3c14099c9ee7166b3202953c27877ce145e9d06f23dc81059779a6819d93812a5e3ce
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Charles Lowell
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## Rumm: a tasty tool for pirates and hackers
|
2
|
+
|
3
|
+
Rumm is a command line interface and API to rackspace. You can use it
|
4
|
+
to easily build and manage infrastructure for great good.
|
5
|
+
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Authenticate with rackspace
|
10
|
+
|
11
|
+
rumm login
|
12
|
+
username: joe
|
13
|
+
password: ****
|
14
|
+
logged in, credentials written to ~/.netrc
|
15
|
+
|
16
|
+
|
17
|
+
Now we can see the list of servers we have available:
|
18
|
+
|
19
|
+
$ rumm show servers
|
20
|
+
you don't have any servers, but you can create on with:
|
21
|
+
rumm create server
|
22
|
+
|
23
|
+
Create the server:
|
24
|
+
|
25
|
+
rumm create server
|
26
|
+
created server divine-reef
|
27
|
+
id: 52415800-8b69-11e0-9b19-734f565bc83b, hostId: e4d909c290d0fb1ca068ffaddf22cbd0, ip: 67.23.10.138, image: CentOS 5.2
|
28
|
+
|
29
|
+
Create the database:
|
30
|
+
|
31
|
+
rumm create databaseinstance #=> POST databaseintsances
|
32
|
+
created databaseinstance little-fork
|
33
|
+
id: 623, username: 'username', password: 'password', databases: production
|
34
|
+
|
35
|
+
In order to allow for a multilpe server nodes, and the ability to
|
36
|
+
bring up new server nodes without changing the public IP of our
|
37
|
+
application, we'll create a load balancer to handle traffic, and then
|
38
|
+
add our server to it:
|
39
|
+
|
40
|
+
rumm create loadbalancer #=> POST loadbalancers
|
41
|
+
created loadbalancer tranquil-snowflake
|
42
|
+
id: 220, port: 80, protocol: http, algorithm: random, virtualIps: 10.1.1.1, fd24:f480:ce44:91bc:1af2:15ff:0000:0005
|
43
|
+
|
44
|
+
rumm create node on loadbalancer tranquil-snowflake
|
45
|
+
created node loadbalancer:tranquil-snowflake
|
46
|
+
id: 410, address: 67.23.10.138, port: 3000, condition: ENABLED, status: ONLINE, weight: 10, type: PRIMARY
|
data/Rakefile
ADDED
data/app.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
class AttachmentsController < MVCLI::Controller
|
2
|
+
requires :compute
|
3
|
+
requires :volumes
|
4
|
+
|
5
|
+
def index
|
6
|
+
#Maybe it would be best to give better information about the
|
7
|
+
#attachments?
|
8
|
+
#Maybe list the volume information rather than attachment info
|
9
|
+
server.attachments.all
|
10
|
+
end
|
11
|
+
|
12
|
+
def attach
|
13
|
+
server.attach_volume volume
|
14
|
+
end
|
15
|
+
|
16
|
+
def detach
|
17
|
+
id = volume.id
|
18
|
+
attachment(id).detach
|
19
|
+
end
|
20
|
+
|
21
|
+
def show
|
22
|
+
id = volume.id
|
23
|
+
attachment id
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def volume
|
29
|
+
volumes.all.find {|v| v.display_name == params[:id]} or fail Fog::Errors::NotFound
|
30
|
+
end
|
31
|
+
|
32
|
+
def server
|
33
|
+
compute.servers.all.find {|s| s.name == params[:server_id]} or fail Fog::Errors::NotFound
|
34
|
+
end
|
35
|
+
|
36
|
+
def attachment vol_id
|
37
|
+
server.attachments.find {|a| a.volume_id == vol_id} or fail Fog::Errors::NotFound
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'json'
|
3
|
+
require 'netrc'
|
4
|
+
|
5
|
+
class AuthenticationController < MVCLI::Controller
|
6
|
+
|
7
|
+
requires :user
|
8
|
+
|
9
|
+
def login
|
10
|
+
#Check if they're already logged in
|
11
|
+
#if(they're logged in)
|
12
|
+
# prompt("you sure bout that?")
|
13
|
+
login_info = user
|
14
|
+
username = login_info.name
|
15
|
+
password = login_info.password
|
16
|
+
|
17
|
+
uri = URI('https://identity.api.rackspacecloud.com/v2.0/tokens')
|
18
|
+
req = Net::HTTP::Post.new(uri)
|
19
|
+
req['Content-Type'] = 'application/json'
|
20
|
+
req.body = {auth: {passwordCredentials: {username: username, password: password}}}.to_json
|
21
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |https|
|
22
|
+
https.request req
|
23
|
+
end
|
24
|
+
user_info = Map(JSON.parse res.body)
|
25
|
+
|
26
|
+
uri = URI("https://identity.api.rackspacecloud.com/v2.0/users/#{user_info.access.user.id}/OS-KSADM/credentials/RAX-KSKEY:apiKeyCredentials")
|
27
|
+
req = Net::HTTP::Get.new(uri, initheader = {'X-Auth-Token' => user_info.access.token.id})
|
28
|
+
req['Content-Type'] = 'application/json'
|
29
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |https|
|
30
|
+
https.request req
|
31
|
+
end
|
32
|
+
|
33
|
+
user_credentials = Map(JSON.parse res.body)
|
34
|
+
|
35
|
+
netrc = Netrc.read
|
36
|
+
netrc['api.rackspace.com'] = username, user_credentials["RAX-KSKEY:apiKeyCredentials"].apiKey
|
37
|
+
netrc.save
|
38
|
+
|
39
|
+
user_info
|
40
|
+
end
|
41
|
+
|
42
|
+
def logout
|
43
|
+
n = Netrc.read
|
44
|
+
n.delete 'api.rackspace.com'
|
45
|
+
n.save
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class ContainersController < MVCLI::Controller
|
2
|
+
requires :containers
|
3
|
+
requires :naming
|
4
|
+
|
5
|
+
def index
|
6
|
+
containers.all
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
options = {
|
11
|
+
key: naming.generate_name(nil, nil)
|
12
|
+
}
|
13
|
+
containers.create options
|
14
|
+
end
|
15
|
+
|
16
|
+
def show
|
17
|
+
directory
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy
|
21
|
+
#Note, cannot destroy a container with files in it
|
22
|
+
directory.tap do |d|
|
23
|
+
d.destroy
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def directory
|
30
|
+
index.find {|d| d.key == params[:id]} or fail Fog::Errors::NotFound
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class DatabasesController < MVCLI::Controller
|
2
|
+
|
3
|
+
requires :instances
|
4
|
+
requires :databases
|
5
|
+
requires :naming
|
6
|
+
|
7
|
+
def index
|
8
|
+
d = databases
|
9
|
+
d.instance = instance
|
10
|
+
d.all
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
d = databases
|
15
|
+
d.instance = instance
|
16
|
+
find_database_in d
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
d = databases
|
21
|
+
d.instance = instance
|
22
|
+
d.create ({name: naming.generate_name("d", "b")})
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
d = databases
|
27
|
+
d.instance = instance
|
28
|
+
db = find_database_in(d)
|
29
|
+
db.destroy
|
30
|
+
return db
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def instance
|
36
|
+
instances.find{|i| i.name == params[:instance_id]} or fail Fog::Errors::NotFound
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def find_database_in instance
|
41
|
+
instance.find{|d| d.name == params[:id]} or fail Fog::Errors::NotFound
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class FilesController < MVCLI::Controller
|
2
|
+
requires :containers
|
3
|
+
|
4
|
+
def index
|
5
|
+
container.all
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
options = {
|
10
|
+
:key => params[:id],
|
11
|
+
:body => File.open(File.expand_path "nouns.txt")
|
12
|
+
}
|
13
|
+
container.create options
|
14
|
+
end
|
15
|
+
|
16
|
+
def show
|
17
|
+
file
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy
|
21
|
+
file.destroy
|
22
|
+
end
|
23
|
+
|
24
|
+
def download
|
25
|
+
File.open((File.expand_path "download-" + params[:id]), 'w') do | f |
|
26
|
+
container.get(params[:id]) do | data, remaining, content_length |
|
27
|
+
f.syswrite data
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def container
|
35
|
+
containers.find{|c| c.key == params[:container_id]}.files or fail Fog::Errors::NotFound
|
36
|
+
end
|
37
|
+
|
38
|
+
def file
|
39
|
+
container.find{|f| f.key == params[:id]} or fail Fog::Errors::NotFound
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class InstancesController < MVCLI::Controller
|
2
|
+
|
3
|
+
requires :instances
|
4
|
+
requires :naming
|
5
|
+
|
6
|
+
def index
|
7
|
+
instances.all
|
8
|
+
end
|
9
|
+
|
10
|
+
def show
|
11
|
+
instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
options = {
|
16
|
+
name: naming.generate_name('d', 'i'),
|
17
|
+
flavor_id: 1,
|
18
|
+
volume_size: 1,
|
19
|
+
}
|
20
|
+
instances.create options
|
21
|
+
end
|
22
|
+
|
23
|
+
def destroy
|
24
|
+
instance.tap do |i|
|
25
|
+
i.destroy
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def instance
|
32
|
+
index.find {|i| i.name == params[:id]} or fail Fog::Errors::NotFound
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class LoadbalancersController < MVCLI::Controller
|
2
|
+
requires :loadbalancers
|
3
|
+
requires :command
|
4
|
+
|
5
|
+
def index
|
6
|
+
loadbalancers.all
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
balancer
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
template = Loadbalancers::CreateForm
|
15
|
+
argv = MVCLI::Argv.new command.argv
|
16
|
+
form = template.new argv.options
|
17
|
+
form.validate!
|
18
|
+
loadbalancers.create form.value
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy
|
22
|
+
balancer.tap do |b|
|
23
|
+
b.destroy
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def balancer
|
30
|
+
index.find {|s| s.name == params[:id]} or fail Fog::Erors::NotFound
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class NodesController < MVCLI::Controller
|
2
|
+
requires :loadbalancers
|
3
|
+
requires :nodes
|
4
|
+
|
5
|
+
def index
|
6
|
+
n = nodes
|
7
|
+
n.load_balancer = load_balancer
|
8
|
+
n.all
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
n = nodes
|
13
|
+
n.load_balancer = load_balancer
|
14
|
+
find_node_in n
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
n = nodes
|
19
|
+
n.load_balancer = load_balancer
|
20
|
+
options = {
|
21
|
+
address: params[:ip_address],
|
22
|
+
#address: "198.61.221.220",
|
23
|
+
condition: "ENABLED",
|
24
|
+
port: 80
|
25
|
+
}
|
26
|
+
n.create options
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy
|
30
|
+
n = nodes
|
31
|
+
n.load_balancer = load_balancer
|
32
|
+
find_node_in(n).destroy
|
33
|
+
:id
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def load_balancer
|
39
|
+
loadbalancers.find{|l| l.name == params[:loadbalancer_id]} or fail Fog::Errors::NotFound
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_node_in loadbalancer
|
43
|
+
loadbalancer.find{|n| n.id.to_s == params[:id]} or fail Fog::Errors::NotFound
|
44
|
+
end
|
45
|
+
end
|