stackfu 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +2 -3
- data/Rakefile +3 -3
- data/lib/stackfu/app.rb +10 -0
- data/lib/stackfu/commands/deploy_command.rb +19 -3
- data/lib/stackfu/commands/list_command.rb +3 -2
- data/lib/stackfu/helpers/rendering.rb +4 -1
- data/spec/fixtures/scripts/password.json +12 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/stackfu/commands/deploy_command_spec.rb +59 -0
- data/spec/stackfu/rendering_spec.rb +187 -0
- data/stackfu.gemspec +9 -9
- metadata +12 -13
- data/firewall/config/03-scripts.yml +0 -6
- data/firewall/script/configure_ufw.sh.erb +0 -9
- data/firewall/script/install_ufw.sh.erb +0 -7
data/Manifest
CHANGED
@@ -9,13 +9,10 @@ bin/stackfu
|
|
9
9
|
firewall/config/01-controls.yml
|
10
10
|
firewall/config/02-requirements.yml
|
11
11
|
firewall/config/03-executions.yml
|
12
|
-
firewall/config/03-scripts.yml
|
13
12
|
firewall/config/04-validations.yml
|
14
13
|
firewall/executables/configure_ufw.sh.erb
|
15
14
|
firewall/executables/install_ufw.sh.erb
|
16
15
|
firewall/script.yml
|
17
|
-
firewall/script/configure_ufw.sh.erb
|
18
|
-
firewall/script/install_ufw.sh.erb
|
19
16
|
lib/stackfu.rb
|
20
17
|
lib/stackfu/api_hooks.rb
|
21
18
|
lib/stackfu/app.rb
|
@@ -43,6 +40,7 @@ spec/fixtures/scripts/firewall.json
|
|
43
40
|
spec/fixtures/scripts/mongo.json
|
44
41
|
spec/fixtures/scripts/none.json
|
45
42
|
spec/fixtures/scripts/not_found.json
|
43
|
+
spec/fixtures/scripts/password.json
|
46
44
|
spec/fixtures/scripts/script_not_found.json
|
47
45
|
spec/fixtures/servers/all.json
|
48
46
|
spec/fixtures/servers/cannot_deploy.json
|
@@ -57,6 +55,7 @@ spec/stackfu/commands/dump_command_spec.rb
|
|
57
55
|
spec/stackfu/commands/generate_command_spec.rb
|
58
56
|
spec/stackfu/commands/list_command_spec.rb
|
59
57
|
spec/stackfu/commands/publish_command_spec.rb
|
58
|
+
spec/stackfu/rendering_spec.rb
|
60
59
|
stackfu-installer/config/01-controls.yml
|
61
60
|
stackfu-installer/config/02-requirements.yml
|
62
61
|
stackfu-installer/config/03-executions.yml
|
data/Rakefile
CHANGED
@@ -4,15 +4,15 @@ require 'rake/testtask'
|
|
4
4
|
|
5
5
|
require 'echoe'
|
6
6
|
|
7
|
-
Echoe.new('stackfu', '0.1.
|
7
|
+
Echoe.new('stackfu', '0.1.4') do |p|
|
8
8
|
p.description = "StackFu Backend"
|
9
9
|
p.url = "http://stackfu.com/cli"
|
10
10
|
p.author = "Felipe Coury"
|
11
11
|
p.email = "felipe@stackfu.com"
|
12
12
|
p.ignore_pattern = ["tmp/*", "script/*"]
|
13
13
|
p.dependencies = [
|
14
|
-
['activeresource','>= 2.3.
|
15
|
-
['activesupport','>= 2.3.
|
14
|
+
['activeresource','>= 2.3.9'],
|
15
|
+
['activesupport','>= 2.3.9'],
|
16
16
|
['rainbow', '>=1.0.4'],
|
17
17
|
['highline', '>=1.5.1'],
|
18
18
|
['httparty', '>=0.4.5']
|
data/lib/stackfu/app.rb
CHANGED
@@ -26,6 +26,16 @@ module StackFu
|
|
26
26
|
"Please check if your internet connection is active. If you think this problem is not in your end, please report it by emailing support@stackfu.com or try again in a few minutes."
|
27
27
|
raise if $dev
|
28
28
|
|
29
|
+
rescue ActiveResource::ClientError
|
30
|
+
error "There was an error contacting StackFu backend: #{$!.message}.",
|
31
|
+
"Please report this problem at support@stackfu.com or try again in a few minutes."
|
32
|
+
raise if $dev
|
33
|
+
|
34
|
+
rescue ActiveResource::ServerError
|
35
|
+
error "There was an error contacting StackFu backend: #{$!.message}.",
|
36
|
+
"Please report this problem at support@stackfu.com or try again in a few minutes."
|
37
|
+
raise if $dev
|
38
|
+
|
29
39
|
rescue ActiveResource::UnauthorizedAccess
|
30
40
|
error "Access denied for user '#{$config[:login]}'",
|
31
41
|
"Please check the credentials provided on file #{ENV['HOME']}/.stackfu and run 'stackfu config' for changing it."
|
@@ -93,7 +93,17 @@ module StackFu::Commands
|
|
93
93
|
|
94
94
|
server_id = server.id
|
95
95
|
server.id = server.slug
|
96
|
-
|
96
|
+
begin
|
97
|
+
deployment = server.post(:deploy, {}, { :id => server_id, :script_id => target.slug, :params => params }.to_json)
|
98
|
+
rescue ActiveResource::ClientError
|
99
|
+
if $!.message =~ /406/
|
100
|
+
puts "Error: ".foreground(:red) + "Cannot deploy - there is another deploy queued or running for this server."
|
101
|
+
return
|
102
|
+
else
|
103
|
+
raise
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
97
107
|
deployment = JSON.parse(deployment.body)
|
98
108
|
|
99
109
|
if options[:"no-follow"]
|
@@ -108,6 +118,8 @@ module StackFu::Commands
|
|
108
118
|
|
109
119
|
from = nil
|
110
120
|
last_status = 'queued'
|
121
|
+
finished = false
|
122
|
+
|
111
123
|
while true
|
112
124
|
opts = {}
|
113
125
|
opts['from_id'] = from if from
|
@@ -123,8 +135,7 @@ module StackFu::Commands
|
|
123
135
|
puts "---------- " + " SCRIPT STARTED ".foreground(:white).bright.background(:blue) + " ----------"
|
124
136
|
puts ""
|
125
137
|
elsif status == 'finished'
|
126
|
-
|
127
|
-
puts "---------- " + " SCRIPT FINISHED ".foreground(:white).bright.background(:blue) + " ----------"
|
138
|
+
finished = true
|
128
139
|
end
|
129
140
|
last_status = status
|
130
141
|
end
|
@@ -132,6 +143,11 @@ module StackFu::Commands
|
|
132
143
|
from = logs["last_id"]
|
133
144
|
print logs["contents"]
|
134
145
|
|
146
|
+
if finished
|
147
|
+
puts ""
|
148
|
+
puts "---------- " + " SCRIPT FINISHED ".foreground(:white).bright.background(:blue) + " ----------"
|
149
|
+
end
|
150
|
+
|
135
151
|
break if logs["status"] == "finished" or logs["status"] == "failed"
|
136
152
|
end
|
137
153
|
|
@@ -13,18 +13,19 @@ module StackFu::Commands
|
|
13
13
|
|
14
14
|
TableAttributes = {
|
15
15
|
Server => [
|
16
|
-
[:name, :key, :ip, :
|
16
|
+
[:name, :key, :ip, :verified, :last_seen],
|
17
17
|
lambda do |item|
|
18
18
|
last_seen = item.last_checked_in if item.respond_to?(:last_checked_in)
|
19
19
|
|
20
20
|
if last_seen
|
21
21
|
last_seen = distance_of_time_in_words(Time.now, Time.parse(last_seen))
|
22
22
|
last_seen = "#{last_seen} ago"
|
23
|
+
validated = "yes"
|
23
24
|
else
|
24
25
|
last_seen = "- never -"
|
26
|
+
validated = ""
|
25
27
|
end
|
26
28
|
|
27
|
-
validated = item.validated? ? "yes" : ""
|
28
29
|
|
29
30
|
[item.slug, item._id, item.ip, validated, last_seen]
|
30
31
|
end,
|
@@ -15,7 +15,7 @@ module StackFu
|
|
15
15
|
stack.controls.each do |c|
|
16
16
|
if (opt = options[c.name.to_sym])
|
17
17
|
case c._type
|
18
|
-
when "Textbox"
|
18
|
+
when "Textbox", "Password"
|
19
19
|
params[c.name] = opt if opt
|
20
20
|
|
21
21
|
when "Numericbox"
|
@@ -43,6 +43,9 @@ module StackFu
|
|
43
43
|
|
44
44
|
when "Numericbox"
|
45
45
|
params[c.name] = ask(" #{c.label.rjust(max_length)}: ", Integer)
|
46
|
+
|
47
|
+
when "Password"
|
48
|
+
params[c.name] = ask(" #{c.label.rjust(max_length)}: ") { |q| q.echo = "*" }
|
46
49
|
|
47
50
|
end
|
48
51
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Etag: "b9e3a93cd52f06d0b7cf83233796e8a6"
|
3
|
+
Connection: Keep-Alive
|
4
|
+
Content-Type: application/json; charset=utf-8
|
5
|
+
Date: Sat, 04 Sep 2010 16:59:55 GMT
|
6
|
+
Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-12-24)
|
7
|
+
X-Runtime: 0.323121
|
8
|
+
Content-Length: 1660
|
9
|
+
Cache-Control: max-age=0, private, must-revalidate
|
10
|
+
Set-Cookie: _stackfu_session=BAh7ByIPc2Vzc2lvbl9pZCIlMThjNWIzN2IyNmVmYzIxZWQ1NjE2MDY2ODQ5NWE2OTMiGXdhcmRlbi51c2VyLnVzZXIua2V5WwciCVVzZXJvOhNCU09OOjpPYmplY3RJRAY6CkBkYXRhWxFpUWkBgml%2BaXNpAdRpAYlpAehpM2kBwWkAaQBpCA%3D%3D--cf9903a5a7a8da8f8ca044431cb5a249b9e2a60e; path=/; HttpOnly
|
11
|
+
|
12
|
+
{"slug":"firewall","name":"firewall","controls":[{"name":"password","label":"Password","_id":"4c82796ed489e82ec1000006","_type":"Password","type":"Password","hint":"separate by comma's"},{"name":"Ports","label":"Ports","_id":"4c82796ed489e82ec1000005","_type":"Textbox","type":"Textbox","hint":"separate by comma's"}],"created_at":"2010-09-04T13:53:02-03:00","updated_at":"2010-09-04T13:53:02-03:00","_id":"4c82796ed489e82ec1000008","validations":[{"body":"test -x ufw","_id":"4c82796ed489e82ec1000002","_type":"ExecutableExists","params":{"data":"ufw"},"description":"File ufw exists and is executable"}],"user_id":"4c82796ed489e82ec1000003","requirements":[{"body":"test -x apt-get","_id":"4c82796ed489e82ec1000001","_type":"ExecutableExists","params":{"data":"apt-get"},"description":"File apt-get exists and is executable"}],"executions":[{"body":" # \n # configure_ufw.sh\n # Tue Dec 01 15:06:48 -0200 2009\n #\n\n apt-get update\n apt-get install -y ufw\n","_id":"4c82796ed489e82ec1000006","description":"Install Ufw","watching_user_ids":[]},{"body":" # \n # install_ufw.sh\n # Tue Dec 01 15:06:48 -0200 2009\n #\n\n ufw default deny\n <% ports.split(\",\").each do |port| %>\n ufw allow <%= port %> \n <% end %>\n","_id":"4c82796ed489e82ec1000007","description":"Configure Ufw","watching_user_ids":[]}],"description":"Set up a firewall for your server to improve security.\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n Praesent eget erat libero, id malesuada tortor.\n Donec pharetra sapien et nulla ultricies ac pharetra neque vulputate.","watching_user_ids":[]}
|
data/spec/spec_helper.rb
CHANGED
@@ -44,6 +44,13 @@ module StackFuHelpers
|
|
44
44
|
request.to_return(read_fixture(fixture))
|
45
45
|
end
|
46
46
|
|
47
|
+
def prepare_status(method, uri, status)
|
48
|
+
request = stub_request(method,
|
49
|
+
"#{StackFu::API.gsub("http://", "http://abc123:X@")}#{uri}")
|
50
|
+
request.to_return(:status => status)
|
51
|
+
|
52
|
+
end
|
53
|
+
|
47
54
|
def when_asked_to_choose(what, options)
|
48
55
|
$actions << { :type => "choose", :action => options.merge(:prompt => what) }
|
49
56
|
end
|
@@ -2,11 +2,70 @@
|
|
2
2
|
require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
|
3
3
|
|
4
4
|
describe StackFu::Commands::DeployCommand do
|
5
|
+
context 'rendering controls do' do
|
6
|
+
it "tells the user if there is another deployment running" do
|
7
|
+
prepare(:get, '/servers/webbynode.json')
|
8
|
+
prepare(:get, '/scripts/password.json')
|
9
|
+
|
10
|
+
when_asked " Password: ", :answer => "mama mia"
|
11
|
+
when_asked " Ports: ", :answer => "80,23,22"
|
12
|
+
|
13
|
+
disagree_of "Continue with script installation?\n"
|
14
|
+
|
15
|
+
command "deploy password webbynode"
|
16
|
+
|
17
|
+
stdout.should =~ /Aborted./
|
18
|
+
end
|
19
|
+
|
20
|
+
it "shows review for password if passed as parameter" do
|
21
|
+
prepare(:get, '/servers/webbynode.json')
|
22
|
+
prepare(:get, '/scripts/password.json')
|
23
|
+
|
24
|
+
when_asked " Ports: ", :answer => "80,23,22"
|
25
|
+
|
26
|
+
disagree_of "Continue with script installation?\n"
|
27
|
+
|
28
|
+
command "deploy password webbynode --password=mamamia"
|
29
|
+
|
30
|
+
stdout.should =~ /Password: mamamia/
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
5
34
|
it "presents the options when none given" do
|
6
35
|
command "deploy"
|
7
36
|
stdout.should =~ /You have to tell which script you want to deploy and to which server./
|
8
37
|
end
|
9
38
|
|
39
|
+
it "tells the user if there is another deployment running" do
|
40
|
+
prepare(:get, '/servers/webbynode.json')
|
41
|
+
prepare(:get, '/scripts/firewall.json')
|
42
|
+
prepare_status(:post, '/servers/webbynode/deploy.json', [406, "This server already has a deployment queued or running"])
|
43
|
+
|
44
|
+
when_asked " Ports: ", :answer => "80,23,22"
|
45
|
+
|
46
|
+
agree_with "Continue with script installation?\n"
|
47
|
+
|
48
|
+
command "deploy firewall webbynode"
|
49
|
+
|
50
|
+
stdout.should =~ /Error:/
|
51
|
+
stdout.should =~ /Cannot deploy/
|
52
|
+
end
|
53
|
+
|
54
|
+
it "tells the user when an unexpected error occurs" do
|
55
|
+
prepare(:get, '/servers/webbynode.json')
|
56
|
+
prepare(:get, '/scripts/firewall.json')
|
57
|
+
prepare_status(:post, '/servers/webbynode/deploy.json', [500, "Server has received a roundhound kick!"])
|
58
|
+
|
59
|
+
when_asked " Ports: ", :answer => "80,23,22"
|
60
|
+
|
61
|
+
agree_with "Continue with script installation?\n"
|
62
|
+
|
63
|
+
command "deploy firewall webbynode"
|
64
|
+
|
65
|
+
stdout.should =~ /There was an error/
|
66
|
+
stdout.should =~ /Server has received a roundhound kick!/
|
67
|
+
end
|
68
|
+
|
10
69
|
it "deploys a server" do
|
11
70
|
prepare(:get, '/servers/webbynode.json')
|
12
71
|
prepare(:get, '/scripts/firewall.json')
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# Load Spec Helper
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
3
|
+
|
4
|
+
describe StackFu::Rendering do
|
5
|
+
include StackFu::Rendering
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
class Pizza
|
9
|
+
attr_accessor :flavor, :size, :price
|
10
|
+
|
11
|
+
def initialize(flavor, size, price)
|
12
|
+
@flavor = flavor
|
13
|
+
@size = size
|
14
|
+
@price = price
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#fill_values_from_options' do
|
20
|
+
let(:script) { mock('Script') }
|
21
|
+
|
22
|
+
it "renders textboxes" do
|
23
|
+
textbox = mock('Textbox')
|
24
|
+
textbox.stubs(:_type).returns('Textbox')
|
25
|
+
textbox.stubs(:name).returns('ports')
|
26
|
+
textbox.stubs(:label).returns('Ports')
|
27
|
+
|
28
|
+
script.stubs(:controls).returns([textbox])
|
29
|
+
|
30
|
+
when_asked " Ports: ", :answer => "80,23,22"
|
31
|
+
|
32
|
+
render_target({}, script, {})
|
33
|
+
end
|
34
|
+
|
35
|
+
it "renders numericboxes" do
|
36
|
+
numericbox = mock('Numericbox')
|
37
|
+
numericbox.stubs(:_type).returns('Numericbox')
|
38
|
+
numericbox.stubs(:name).returns('port')
|
39
|
+
numericbox.stubs(:label).returns('Port')
|
40
|
+
|
41
|
+
script.stubs(:controls).returns([numericbox])
|
42
|
+
|
43
|
+
when_asked " Port: ", :answer => "80"
|
44
|
+
|
45
|
+
render_target({}, script, {})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "renders passwords" do
|
49
|
+
password = mock('Password')
|
50
|
+
password.stubs(:_type).returns('Password')
|
51
|
+
password.stubs(:name).returns('password')
|
52
|
+
password.stubs(:label).returns('Password')
|
53
|
+
|
54
|
+
script.stubs(:controls).returns([password])
|
55
|
+
|
56
|
+
when_asked " Password: ", :answer => "abcdef"
|
57
|
+
|
58
|
+
render_target({}, script, {})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "lists" do
|
63
|
+
it "renders a list with the object collection and all properties by default" do
|
64
|
+
pizzas = [
|
65
|
+
Pizza.new("Mozzarella", "Large", 14.99),
|
66
|
+
Pizza.new("Margheritta", "Large", 15.99),
|
67
|
+
Pizza.new("Pequenita", nil, 5.99),
|
68
|
+
Pizza.new("Pepperoni", "Large", 17.99)
|
69
|
+
]
|
70
|
+
|
71
|
+
table = table(:class => Pizza, :collection => pizzas, :display => [:flavor, :size, :price], :ansi => false)
|
72
|
+
table.should =~ /^Listing 4 pizzas:/
|
73
|
+
table.should =~ / Flavor Size Price/
|
74
|
+
table.should =~ / ------------ ------ -----/
|
75
|
+
table.should =~ / Mozzarella Large 14.99/
|
76
|
+
table.should =~ / Margheritta Large 15.99/
|
77
|
+
table.should =~ / Pequenita 5.99/
|
78
|
+
table.should =~ / Pepperoni Large 17.99/
|
79
|
+
end
|
80
|
+
|
81
|
+
it "accepts a block and render based on the block" do
|
82
|
+
pizzas = [
|
83
|
+
Pizza.new("Mozzarella", "Large", 14.99),
|
84
|
+
Pizza.new("Margheritta", "Large", 15.99),
|
85
|
+
Pizza.new("Pequenita", nil, 5.99),
|
86
|
+
]
|
87
|
+
|
88
|
+
table = table(:class => Pizza, :collection => pizzas, :display => [:flavor, :size, :price], :ansi => false) do |item|
|
89
|
+
["Mah #{item.flavor}", "#{item.size.try(:downcase)}", item.price + 2]
|
90
|
+
end
|
91
|
+
table.should =~ /^Listing 3 pizzas:/
|
92
|
+
table.should =~ / Flavor Size Price/
|
93
|
+
table.should =~ / ---------------- ------ -----/
|
94
|
+
table.should =~ / Mah Mozzarella large 16.99/
|
95
|
+
table.should =~ / Mah Margheritta large 17.99/
|
96
|
+
table.should =~ / Mah Pequenita 7.99/
|
97
|
+
end
|
98
|
+
|
99
|
+
it "pluralizes the description before the table" do
|
100
|
+
class Dash < Pizza
|
101
|
+
end
|
102
|
+
|
103
|
+
pizzas = [
|
104
|
+
Dash.new("Mozzarella", "Large", 14.99)
|
105
|
+
]
|
106
|
+
|
107
|
+
table = table(:class => Dash, :collection => pizzas, :display => [:flavor, :size, :price], :ansi => false) do |item|
|
108
|
+
["Mah #{item.flavor}", "#{item.size.try(:downcase)}", item.price + 2]
|
109
|
+
end
|
110
|
+
table.should =~ /^Listing 1 dash:/
|
111
|
+
table.should =~ / Flavor Size Price/
|
112
|
+
table.should =~ / --------------- ------ -----/
|
113
|
+
table.should =~ / Mah Mozzarella large 16.99/
|
114
|
+
|
115
|
+
pizzas << Dash.new("Minina", "Large", 14.99)
|
116
|
+
|
117
|
+
table = table(:class => Dash, :collection => pizzas, :display => [:flavor, :size, :price], :ansi => false) do |item|
|
118
|
+
["Mah #{item.flavor}", "#{item.size.try(:downcase)}", item.price + 2]
|
119
|
+
end
|
120
|
+
table.should =~ /^Listing 2 dashes:/
|
121
|
+
table.should =~ / Flavor Size Price/
|
122
|
+
table.should =~ / --------------- ------ -----/
|
123
|
+
table.should =~ / Mah Mozzarella large 16.99/
|
124
|
+
end
|
125
|
+
|
126
|
+
it "renders an empty message if no items" do
|
127
|
+
pizzas = []
|
128
|
+
table = table(:class => Pizza, :collection => pizzas, :display => [:flavor, :size, :price], :ansi => false)
|
129
|
+
table.should =~ /No pizzas./
|
130
|
+
end
|
131
|
+
|
132
|
+
it "renders a custom empty message if no items and custom message passed" do
|
133
|
+
pizzas = []
|
134
|
+
table = table(:class => Pizza, :collection => pizzas,
|
135
|
+
:display => [:flavor, :size, :price], :empty => "Sorry dude, no pizzas!")
|
136
|
+
table.should =~ /Sorry dude, no pizzas!/
|
137
|
+
end
|
138
|
+
|
139
|
+
it "renders two objects with same duck type" do
|
140
|
+
class Animal
|
141
|
+
attr_accessor :name
|
142
|
+
def initialize(name)
|
143
|
+
@name = name
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class Dog < Animal
|
148
|
+
def legs; 4; end
|
149
|
+
end
|
150
|
+
|
151
|
+
class Spider < Animal
|
152
|
+
def legs; 8; end
|
153
|
+
end
|
154
|
+
|
155
|
+
class Fly < Animal
|
156
|
+
def legs; 6; end
|
157
|
+
end
|
158
|
+
|
159
|
+
animals = [Dog.new("Jimmy"), Dog.new("Buddy"), Fly.new("Buggah"), Spider.new("Mommy")]
|
160
|
+
table = table(
|
161
|
+
:class => [Dog, Fly, Spider],
|
162
|
+
:display => [:name, :legs],
|
163
|
+
:collection => animals, :ansi => false
|
164
|
+
)
|
165
|
+
|
166
|
+
table.should =~ /^Listing 2 dogs, 1 fly and 1 spider/
|
167
|
+
table.should =~ / Name Legs /
|
168
|
+
table.should =~ / ------- -----/
|
169
|
+
table.should =~ / Jimmy 4/
|
170
|
+
table.should =~ / Buddy 4/
|
171
|
+
table.should =~ / Buggah 6/
|
172
|
+
table.should =~ / Mommy 8/
|
173
|
+
end
|
174
|
+
|
175
|
+
it "renders a custom headline" do
|
176
|
+
pizzas = [Pizza.new("Mozzarella", "Large", 14.99)]
|
177
|
+
table = table(
|
178
|
+
:class => Pizza,
|
179
|
+
:collection => pizzas,
|
180
|
+
:display => [:flavor, :size, :price],
|
181
|
+
:header => "We have some pizzas for you")
|
182
|
+
|
183
|
+
table.should =~ /^We have some pizzas for you/
|
184
|
+
table.should_not =~ /^Listing 1 pizza/
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
data/stackfu.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{stackfu}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Felipe Coury"]
|
9
|
-
s.date = %q{2010-09-
|
9
|
+
s.date = %q{2010-09-11}
|
10
10
|
s.default_executable = %q{stackfu}
|
11
11
|
s.description = %q{StackFu Backend}
|
12
12
|
s.email = %q{felipe@stackfu.com}
|
13
13
|
s.executables = ["stackfu"]
|
14
14
|
s.extra_rdoc_files = ["CHANGELOG", "README", "README.md", "bin/stackfu", "lib/stackfu.rb", "lib/stackfu/api_hooks.rb", "lib/stackfu/app.rb", "lib/stackfu/commands/command.rb", "lib/stackfu/commands/config_command.rb", "lib/stackfu/commands/deploy_command.rb", "lib/stackfu/commands/dump_command.rb", "lib/stackfu/commands/generate_command.rb", "lib/stackfu/commands/help_command.rb", "lib/stackfu/commands/list_command.rb", "lib/stackfu/commands/publish_command.rb", "lib/stackfu/commands/server_command.rb", "lib/stackfu/date_helper.rb", "lib/stackfu/helpers/providers_credentials.rb", "lib/stackfu/helpers/rendering.rb", "lib/stackfu/operating_systems.rb"]
|
15
|
-
s.files = ["CHANGELOG", "Gemfile", "Manifest", "README", "README.md", "Rakefile", "autotest/discover.rb", "bin/stackfu", "firewall/config/01-controls.yml", "firewall/config/02-requirements.yml", "firewall/config/03-executions.yml", "firewall/config/
|
15
|
+
s.files = ["CHANGELOG", "Gemfile", "Manifest", "README", "README.md", "Rakefile", "autotest/discover.rb", "bin/stackfu", "firewall/config/01-controls.yml", "firewall/config/02-requirements.yml", "firewall/config/03-executions.yml", "firewall/config/04-validations.yml", "firewall/executables/configure_ufw.sh.erb", "firewall/executables/install_ufw.sh.erb", "firewall/script.yml", "lib/stackfu.rb", "lib/stackfu/api_hooks.rb", "lib/stackfu/app.rb", "lib/stackfu/commands/command.rb", "lib/stackfu/commands/config_command.rb", "lib/stackfu/commands/deploy_command.rb", "lib/stackfu/commands/dump_command.rb", "lib/stackfu/commands/generate_command.rb", "lib/stackfu/commands/help_command.rb", "lib/stackfu/commands/list_command.rb", "lib/stackfu/commands/publish_command.rb", "lib/stackfu/commands/server_command.rb", "lib/stackfu/date_helper.rb", "lib/stackfu/helpers/providers_credentials.rb", "lib/stackfu/helpers/rendering.rb", "lib/stackfu/operating_systems.rb", "spec/fixtures/deployments/logs.json", "spec/fixtures/deployments/logs_end.json", "spec/fixtures/deployments/logs_failed.json", "spec/fixtures/deployments/logs_middle.json", "spec/fixtures/scripts/all.json", "spec/fixtures/scripts/create.json", "spec/fixtures/scripts/delete.json", "spec/fixtures/scripts/firewall.json", "spec/fixtures/scripts/mongo.json", "spec/fixtures/scripts/none.json", "spec/fixtures/scripts/not_found.json", "spec/fixtures/scripts/password.json", "spec/fixtures/scripts/script_not_found.json", "spec/fixtures/servers/all.json", "spec/fixtures/servers/cannot_deploy.json", "spec/fixtures/servers/none.json", "spec/fixtures/servers/not_found.json", "spec/fixtures/servers/webbynode.json", "spec/fixtures/servers/webbynode/deploy.json", "spec/spec_helper.rb", "spec/stackfu/api_hooks_spec.rb", "spec/stackfu/commands/deploy_command_spec.rb", "spec/stackfu/commands/dump_command_spec.rb", "spec/stackfu/commands/generate_command_spec.rb", "spec/stackfu/commands/list_command_spec.rb", "spec/stackfu/commands/publish_command_spec.rb", "spec/stackfu/rendering_spec.rb", "stackfu-installer/config/01-controls.yml", "stackfu-installer/config/02-requirements.yml", "stackfu-installer/config/03-executions.yml", "stackfu-installer/config/04-validations.yml", "stackfu-installer/script/dotfiles_installation.sh.erb", "stackfu-installer/script/github_credentials_setup.sh.erb", "stackfu-installer/script/nginx_and_passenger.sh.erb", "stackfu-installer/script/redis_installation.sh.erb", "stackfu-installer/script/resque_installation.sh.erb", "stackfu-installer/script/ruby_environment.sh.erb", "stackfu-installer/script/stackfu.sh.erb", "stackfu-installer/stack.yml", "templates/01-controls.yml.erb", "templates/02-requirements.yml.erb", "templates/03-executions.yml.erb", "templates/04-validations.yml.erb", "templates/script.sh.erb", "templates/stack.yml.erb", "test/fixtures/add_server_error", "test/fixtures/deployment_add", "test/fixtures/deployment_add_error", "test/fixtures/deployments", "test/fixtures/logs", "test/fixtures/logs_partial", "test/fixtures/plugin_add", "test/fixtures/plugin_add_error", "test/fixtures/plugin_deployment_add", "test/fixtures/plugin_not_found", "test/fixtures/plugin_unauthorized", "test/fixtures/plugins", "test/fixtures/plugins_by_name", "test/fixtures/plugins_by_name_other", "test/fixtures/plugins_empty", "test/fixtures/plugins_multiple", "test/fixtures/providers", "test/fixtures/providers_servers", "test/fixtures/server_add", "test/fixtures/server_add_dupe", "test/fixtures/server_add_error", "test/fixtures/server_delete", "test/fixtures/server_delete_error", "test/fixtures/servers", "test/fixtures/servers_by_name", "test/fixtures/servers_empty", "test/fixtures/servers_not_found", "test/fixtures/servers_unauthorized", "test/fixtures/servers_webbynode", "test/fixtures/stack/stackfu-installer/config/01-controls.yml", "test/fixtures/stack/stackfu-installer/config/02-requirements.yml", "test/fixtures/stack/stackfu-installer/config/03-scripts.yml", "test/fixtures/stack/stackfu-installer/config/04-validations.yml", "test/fixtures/stack/stackfu-installer/script/dotfiles_installation.sh.erb", "test/fixtures/stack/stackfu-installer/script/github_credentials_setup.sh.erb", "test/fixtures/stack/stackfu-installer/script/nginx_and_passenger.sh.erb", "test/fixtures/stack/stackfu-installer/script/redis_installation.sh.erb", "test/fixtures/stack/stackfu-installer/script/resque_installation.sh.erb", "test/fixtures/stack/stackfu-installer/script/ruby_environment.sh.erb", "test/fixtures/stack/stackfu-installer/script/stackfu.sh.erb", "test/fixtures/stack/stackfu-installer/stack.yml", "test/fixtures/stack_add", "test/fixtures/stack_add_error", "test/fixtures/stack_add_error_dupe", "test/fixtures/stack_adds_by_name", "test/fixtures/stack_delete_not_found", "test/fixtures/stacks", "test/fixtures/stacks_by_name", "test/fixtures/stacks_by_name_other", "test/fixtures/stacks_empty", "test/fixtures/stacks_multiple", "test/fixtures/stacks_not_found", "test/fixtures/stacks_realworld", "test/fixtures/stacks_stackfu-installer", "test/fixtures/stacks_unauthorized", "test/fixtures/stacks_with_controls", "test/fixtures/users", "test/fixtures/users_no_credentials", "test/fixtures/users_update", "test/support/custom_matchers.rb", "test/support/fixtures.rb", "test/support/io_stub.rb", "test/support/web_fixtures.rb", "test/test_helper.rb", "test/unit/commands/test_command.rb", "test/unit/commands/test_config_command.rb", "test/unit/commands/test_deploy_command.rb", "test/unit/commands/test_dump_command.rb", "test/unit/commands/test_generate_command.rb", "test/unit/commands/test_help_command.rb", "test/unit/commands/test_list_command.rb", "test/unit/commands/test_publish_command.rb", "test/unit/commands/test_server_command.rb", "test/unit/helpers/test_rendering.rb", "test/unit/test_array.rb", "test/unit/test_provider.rb", "test/unit/test_stackfu.rb", "stackfu.gemspec"]
|
16
16
|
s.homepage = %q{http://stackfu.com/cli}
|
17
17
|
s.post_install_message = %q{
|
18
18
|
--==-- StackFu - Server Deployment Engine --==--
|
@@ -38,21 +38,21 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.specification_version = 3
|
39
39
|
|
40
40
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
41
|
-
s.add_runtime_dependency(%q<activeresource>, [">= 2.3.
|
42
|
-
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.
|
41
|
+
s.add_runtime_dependency(%q<activeresource>, [">= 2.3.9"])
|
42
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.9"])
|
43
43
|
s.add_runtime_dependency(%q<rainbow>, [">= 1.0.4"])
|
44
44
|
s.add_runtime_dependency(%q<highline>, [">= 1.5.1"])
|
45
45
|
s.add_runtime_dependency(%q<httparty>, [">= 0.4.5"])
|
46
46
|
else
|
47
|
-
s.add_dependency(%q<activeresource>, [">= 2.3.
|
48
|
-
s.add_dependency(%q<activesupport>, [">= 2.3.
|
47
|
+
s.add_dependency(%q<activeresource>, [">= 2.3.9"])
|
48
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.9"])
|
49
49
|
s.add_dependency(%q<rainbow>, [">= 1.0.4"])
|
50
50
|
s.add_dependency(%q<highline>, [">= 1.5.1"])
|
51
51
|
s.add_dependency(%q<httparty>, [">= 0.4.5"])
|
52
52
|
end
|
53
53
|
else
|
54
|
-
s.add_dependency(%q<activeresource>, [">= 2.3.
|
55
|
-
s.add_dependency(%q<activesupport>, [">= 2.3.
|
54
|
+
s.add_dependency(%q<activeresource>, [">= 2.3.9"])
|
55
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.9"])
|
56
56
|
s.add_dependency(%q<rainbow>, [">= 1.0.4"])
|
57
57
|
s.add_dependency(%q<highline>, [">= 1.5.1"])
|
58
58
|
s.add_dependency(%q<httparty>, [">= 0.4.5"])
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackfu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 4
|
10
|
+
version: 0.1.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Felipe Coury
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-11 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -26,12 +26,12 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 17
|
30
30
|
segments:
|
31
31
|
- 2
|
32
32
|
- 3
|
33
|
-
-
|
34
|
-
version: 2.3.
|
33
|
+
- 9
|
34
|
+
version: 2.3.9
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -42,12 +42,12 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
45
|
+
hash: 17
|
46
46
|
segments:
|
47
47
|
- 2
|
48
48
|
- 3
|
49
|
-
-
|
50
|
-
version: 2.3.
|
49
|
+
- 9
|
50
|
+
version: 2.3.9
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
53
|
- !ruby/object:Gem::Dependency
|
@@ -137,13 +137,10 @@ files:
|
|
137
137
|
- firewall/config/01-controls.yml
|
138
138
|
- firewall/config/02-requirements.yml
|
139
139
|
- firewall/config/03-executions.yml
|
140
|
-
- firewall/config/03-scripts.yml
|
141
140
|
- firewall/config/04-validations.yml
|
142
141
|
- firewall/executables/configure_ufw.sh.erb
|
143
142
|
- firewall/executables/install_ufw.sh.erb
|
144
143
|
- firewall/script.yml
|
145
|
-
- firewall/script/configure_ufw.sh.erb
|
146
|
-
- firewall/script/install_ufw.sh.erb
|
147
144
|
- lib/stackfu.rb
|
148
145
|
- lib/stackfu/api_hooks.rb
|
149
146
|
- lib/stackfu/app.rb
|
@@ -171,6 +168,7 @@ files:
|
|
171
168
|
- spec/fixtures/scripts/mongo.json
|
172
169
|
- spec/fixtures/scripts/none.json
|
173
170
|
- spec/fixtures/scripts/not_found.json
|
171
|
+
- spec/fixtures/scripts/password.json
|
174
172
|
- spec/fixtures/scripts/script_not_found.json
|
175
173
|
- spec/fixtures/servers/all.json
|
176
174
|
- spec/fixtures/servers/cannot_deploy.json
|
@@ -185,6 +183,7 @@ files:
|
|
185
183
|
- spec/stackfu/commands/generate_command_spec.rb
|
186
184
|
- spec/stackfu/commands/list_command_spec.rb
|
187
185
|
- spec/stackfu/commands/publish_command_spec.rb
|
186
|
+
- spec/stackfu/rendering_spec.rb
|
188
187
|
- stackfu-installer/config/01-controls.yml
|
189
188
|
- stackfu-installer/config/02-requirements.yml
|
190
189
|
- stackfu-installer/config/03-executions.yml
|