stackfu 0.1.1 → 0.1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/Gemfile +4 -0
  2. data/Manifest +36 -4
  3. data/Rakefile +1 -1
  4. data/autotest/discover.rb +1 -0
  5. data/firewall/config/01-controls.yml +5 -0
  6. data/firewall/config/02-requirements.yml +4 -0
  7. data/firewall/config/03-executions.yml +6 -0
  8. data/firewall/config/03-scripts.yml +6 -0
  9. data/firewall/config/04-validations.yml +4 -0
  10. data/firewall/executables/configure_ufw.sh.erb +9 -0
  11. data/firewall/executables/install_ufw.sh.erb +7 -0
  12. data/firewall/script/configure_ufw.sh.erb +9 -0
  13. data/firewall/script/install_ufw.sh.erb +7 -0
  14. data/firewall/script.yml +8 -0
  15. data/lib/stackfu/api_hooks.rb +2 -2
  16. data/lib/stackfu/app.rb +5 -5
  17. data/lib/stackfu/commands/command.rb +7 -3
  18. data/lib/stackfu/commands/config_command.rb +1 -1
  19. data/lib/stackfu/commands/deploy_command.rb +53 -61
  20. data/lib/stackfu/commands/dump_command.rb +46 -40
  21. data/lib/stackfu/commands/generate_command.rb +10 -12
  22. data/lib/stackfu/commands/help_command.rb +1 -1
  23. data/lib/stackfu/commands/list_command.rb +76 -22
  24. data/lib/stackfu/commands/publish_command.rb +35 -18
  25. data/lib/stackfu/commands/server_command.rb +124 -124
  26. data/lib/stackfu/date_helper.rb +111 -0
  27. data/lib/stackfu.rb +4 -2
  28. data/spec/fixtures/scripts/all.json +11 -0
  29. data/spec/fixtures/scripts/create.json +10 -0
  30. data/spec/fixtures/scripts/delete.json +10 -0
  31. data/spec/fixtures/scripts/firewall.json +12 -0
  32. data/spec/fixtures/scripts/none.json +12 -0
  33. data/spec/fixtures/scripts/not_found.json +11 -0
  34. data/spec/fixtures/scripts/script_not_found.json +11 -0
  35. data/spec/fixtures/servers/all.json +12 -0
  36. data/spec/fixtures/servers/cannot_deploy.json +0 -0
  37. data/spec/fixtures/servers/deploy.json +290 -0
  38. data/spec/fixtures/servers/none.json +12 -0
  39. data/spec/fixtures/servers/not_found.json +11 -0
  40. data/spec/fixtures/servers/webbynode/deploy.json +12 -0
  41. data/spec/fixtures/servers/webbynode.json +12 -0
  42. data/spec/spec_helper.rb +191 -0
  43. data/spec/stackfu/api_hooks_spec.rb +7 -0
  44. data/spec/stackfu/commands/deploy_command_spec.rb +65 -0
  45. data/spec/stackfu/commands/dump_command_spec.rb +47 -0
  46. data/spec/stackfu/commands/generate_command_spec.rb +90 -0
  47. data/spec/stackfu/commands/list_command_spec.rb +53 -0
  48. data/spec/stackfu/commands/publish_command_spec.rb +67 -0
  49. data/stackfu.gemspec +4 -4
  50. data/templates/02-requirements.yml.erb +8 -10
  51. data/templates/{03-scripts.yml.erb → 03-executions.yml.erb} +3 -3
  52. data/templates/04-validations.yml.erb +1 -2
  53. data/templates/stack.yml.erb +4 -13
  54. data/test/support/fixtures.rb +1 -1
  55. data/test/unit/commands/test_server_command.rb +259 -259
  56. metadata +42 -7
  57. data/test/stack.yml +0 -26
  58. /data/stackfu-installer/config/{03-scripts.yml → 03-executions.yml} +0 -0
@@ -0,0 +1,12 @@
1
+ HTTP/1.1 200 OK
2
+ Etag: "d751713988987e9331980363e24189ce"
3
+ Connection: Keep-Alive
4
+ Content-Type: application/json; charset=utf-8
5
+ Date: Mon, 06 Sep 2010 03:09:00 GMT
6
+ Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-12-24)
7
+ X-Runtime: 0.625119
8
+ Content-Length: 2
9
+ Cache-Control: max-age=0, private, must-revalidate
10
+ Set-Cookie: _stackfu_session=BAh7ByIPc2Vzc2lvbl9pZCIlMGRiYzFmZjlmNGFkNDBjNDlhYzE2ODEwM2E1NDYzM2QiGXdhcmRlbi51c2VyLnVzZXIua2V5WwciCVVzZXJvOhNCU09OOjpPYmplY3RJRAY6CkBkYXRhWxFpUWkBg2kB%2FmkkaQHUaQGJaQHoaQGTaQGPaQBpAGkJ--87aa1578a2f486481a5ccb365970fd9dcd4f1449; path=/; HttpOnly
11
+
12
+ []
@@ -0,0 +1,11 @@
1
+ HTTP/1.1 404 Not Found
2
+ Connection: Keep-Alive
3
+ Content-Type: application/json; charset=utf-8
4
+ Date: Mon, 06 Sep 2010 15:07:35 GMT
5
+ Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-12-24)
6
+ X-Runtime: 0.387455
7
+ Content-Length: 25
8
+ Cache-Control: no-cache
9
+ Set-Cookie: _stackfu_session=BAh7ByIPc2Vzc2lvbl9pZCIlZDI4YjQ5MGRlMTM0NTVkZjZmMTE1OTg2MjEwZGI0ZGIiGXdhcmRlbi51c2VyLnVzZXIua2V5WwciCVVzZXJvOhNCU09OOjpPYmplY3RJRAY6CkBkYXRhWxFpUWkBg2kB%2FmkkaQHUaQGJaQHoaQGTaQGPaQBpAGkJ--283c189facf98f987ce9dce345c20a91db7e03ae; path=/; HttpOnly
10
+
11
+ Server firewall not found
@@ -0,0 +1,12 @@
1
+ HTTP/1.1 200 OK
2
+ Etag: "b2d8ba4761967f030b2ea220620986b1"
3
+ Connection: Keep-Alive
4
+ Content-Type: application/json; charset=utf-8
5
+ Date: Sat, 04 Sep 2010 21:35:47 GMT
6
+ Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-12-24)
7
+ X-Runtime: 0.313166
8
+ Content-Length: 1730
9
+ Cache-Control: max-age=0, private, must-revalidate
10
+ Set-Cookie: _stackfu_session=BAh7ByIPc2Vzc2lvbl9pZCIlYzZiMDZlNmJlZTgwZTU3ODA1NTgzMjk1YmI4N2FhN2EiGXdhcmRlbi51c2VyLnVzZXIua2V5WwciCVVzZXJvOhNCU09OOjpPYmplY3RJRAY6CkBkYXRhWxFpUWkBgml%2BaXNpAdRpAYlpAehpM2kBwWkAaQBpCA%3D%3D--b119069c65fff79fbc923dc31cc993334e278c79; path=/; HttpOnly
11
+
12
+ {"stack":{"slug":null,"_id":"4c82bbb3d489e856ce000005","scripts":[{"slug":"firewall","name":"firewall","controls":[{"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":[]}]},"provider_id":null,"server_id":"4c82796ed489e82ec1000017","_id":"4c82bbb3d489e856ce000006","params":{"ports":"80,23,22"},"status":"queued"}
@@ -0,0 +1,12 @@
1
+ HTTP/1.1 200 OK
2
+ Etag: "41c3b7d21d2e41ec1838513f1e889bfa"
3
+ Connection: Keep-Alive
4
+ Content-Type: application/json; charset=utf-8
5
+ Date: Sat, 04 Sep 2010 20:33:27 GMT
6
+ Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-12-24)
7
+ X-Runtime: 0.444424
8
+ Content-Length: 451
9
+ Cache-Control: max-age=0, private, must-revalidate
10
+ Set-Cookie: _stackfu_session=BAh7ByIPc2Vzc2lvbl9pZCIlNDZkMzg5M2MxOWFmNTFmY2U3YmZjODMzNTFjNDYwMjkiGXdhcmRlbi51c2VyLnVzZXIua2V5WwciCVVzZXJvOhNCU09OOjpPYmplY3RJRAY6CkBkYXRhWxFpUWkBgml%2BaXNpAdRpAYlpAehpM2kBwWkAaQBpCA%3D%3D--4d15caee746e09b3d7fd6c7a63937dbf32696736; path=/; HttpOnly
11
+
12
+ {"slug":"webbynode","name":"Webbynode","updated_at":"2010-09-04T17:32:56-03:00","_id":"4c82796ed489e82ec1000017","provider_name":"Linnode","user_id":"4c82796ed489e82ec1000003","ip":"123.45.678.90","description":"Nunc hendrerit blandit ultrices. Cras pellentesque turpis et dolo\n molestie vitae lacinia nisi iaculis. Pellentesque vitae quam enim. Vivamus dui quam,\n aliquet in condimentum vel, placerat sit amet quam. Aliquam ac sollicitudin dui."}
@@ -0,0 +1,191 @@
1
+ # Require RSpec
2
+ require 'rubygems'
3
+ require 'rspec'
4
+ require 'webmock/rspec'
5
+ require 'pp'
6
+
7
+ # Load Webbynode Class
8
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'stackfu')
9
+
10
+ # Set Testing Environment
11
+ $testing = true
12
+ WebMock.disable_net_connect!
13
+ HighLine.track_eof = false
14
+
15
+ # Reads out a file from the fixtures directory
16
+
17
+ module StackFuHelpers
18
+ def read_fixture(file)
19
+ File.read(File.join(File.dirname(__FILE__), "fixtures", file))
20
+ end
21
+
22
+ def prepare_raise(method, uri, error)
23
+ request = stub_request(method,
24
+ "#{StackFu::API.gsub("http://", "http://abc123:X@")}#{uri}")
25
+ request.to_raise(error)
26
+ end
27
+
28
+ def prepare(method, uri, fixture=uri, options=nil)
29
+ request = stub_request(method,
30
+ "#{StackFu::API.gsub("http://", "http://abc123:X@")}#{uri}")
31
+
32
+ request = request.with(options) if options
33
+
34
+ request.to_return(read_fixture(fixture))
35
+ end
36
+
37
+ def when_asked_to_choose(what, options)
38
+ $actions << { :type => "choose", :action => options.merge(:prompt => what) }
39
+ end
40
+
41
+ def when_asked(what, options)
42
+ $actions << { :type => "ask", :action => [what, options[:answer]] }
43
+ end
44
+
45
+ def agree_with(what)
46
+ $actions << { :type => "agree", :action => what }
47
+ end
48
+
49
+ def disagree_of(what)
50
+ $actions << { :type => "disagree", :action => what }
51
+ end
52
+
53
+ def redirect_stdout
54
+ @orig_stdout = $stdout
55
+ $stdout = StringIO.new
56
+ end
57
+
58
+ def command(cmd, settings_present=true)
59
+ redirect_stdout
60
+ cmd ||= ""
61
+ StackFu::App.expects(:settings?).returns(settings_present)
62
+ if settings_present
63
+ StackFu::App.any_instance.expects(:load_config).returns({ :login => "flipper", :token => "abc123" })
64
+ end
65
+ StackFu::App.new(cmd.split(" ")).start
66
+ end
67
+
68
+ def stdout
69
+ if @orig_stdout
70
+ $stdout.rewind
71
+ @result = $stdout.read
72
+ $stdout = @orig_stdout
73
+ @orig_stdout = nil
74
+ end
75
+
76
+ @result
77
+ end
78
+
79
+ def debug(s)
80
+ @orig_stdout.puts s
81
+ end
82
+ end
83
+
84
+ Rspec.configure do |config|
85
+ config.mock_with :mocha
86
+
87
+ config.include WebMock
88
+ config.include StackFuHelpers
89
+ config.include Rspec::Matchers
90
+
91
+ config.before(:each) do
92
+ $actions = []
93
+ $asked = []
94
+ end
95
+
96
+ config.after(:each) do
97
+ stdout if @orig_stdout
98
+ asked = $asked.map { |s| " - #{s}" }.join("\n")
99
+ unless $actions.empty?
100
+ questions = $actions.map do |q|
101
+ info = case q[:type]
102
+ when "ask"
103
+ q[:action].first
104
+
105
+ when "choose"
106
+ txt = "'#{q[:action][:prompt]}'"
107
+ txt << " with options '#{q[:action][:with_options].join(", ")}'" if q[:action][:with_options]
108
+ else
109
+ q[:action]
110
+ end
111
+
112
+ " - #{q[:type]} #{info}"
113
+ end.join("\n")
114
+ fail "Expected questions not asked:\n#{questions}\nQuestions responded:\n#{asked}\n"
115
+ end
116
+ end
117
+ end
118
+
119
+ module Kernel
120
+ def choose(*items, &details)
121
+ if (action = $actions.first)
122
+ if action[:type] == "choose"
123
+ item = OpenStruct.new
124
+ class << item
125
+ def choice(*args)
126
+ (self.choices||=[]) << args
127
+ end
128
+ end
129
+
130
+ details.call item
131
+
132
+ exp_action = $actions.shift[:action]
133
+ item.prompt.should == exp_action[:prompt]
134
+
135
+ exp_action[:with_options].try(:each) do |opt|
136
+ item.choices.flatten.include?(opt).should == true
137
+ end
138
+
139
+ if (answer = exp_action[:answer]).is_a?(Numeric)
140
+ item.choices[answer][0]
141
+ else
142
+ answer
143
+ end
144
+ end
145
+ else
146
+ fail "Unexpected choose"
147
+ end
148
+ end
149
+
150
+ def ask(question, answer_type = String, &details)
151
+ if (action = $actions.first)
152
+ matches = if (expected = action[:action].first).is_a?(Regexp)
153
+ question =~ expected
154
+ else
155
+ question == expected
156
+ end
157
+
158
+ if action[:type] == "ask" and matches
159
+ $asked << "responded to ask #{action[:action].first} with #{action[:action].last}"
160
+ exp_action = $actions.shift
161
+ result = exp_action[:action].last
162
+ return result
163
+ end
164
+
165
+ fail "Expected to #{action[:type]} #{action[:action].inspect} but asked #{question.inspect}"
166
+ else
167
+ fail "Unexpected ask #{question.inspect}"
168
+ end
169
+ end
170
+
171
+ def agree(yes_or_no_question, character = nil)
172
+ action = $actions.first
173
+ if action and action[:action] == yes_or_no_question
174
+ if action[:type] == "agree" or action[:type] == "disagree"
175
+ $asked << "#{action[:type]}d to #{action[:action]}"
176
+ result = $actions.shift[:type] == "agree"
177
+ # d "#{action[:type]} #{yes_or_no_question} => #{result}"
178
+ return result
179
+ end
180
+ end
181
+
182
+ if action
183
+ fail "Expected to #{action[:type]} #{action[:action].inspect} but asked to agree with #{yes_or_no_question.inspect}"
184
+ else
185
+ fail "Unexpected agreement #{yes_or_no_question.inspect}"
186
+ end
187
+ end
188
+ end
189
+
190
+ def d(x); $stderr.puts x.pretty_inspect; end
191
+ def rd(x); $stderr.puts x; end
@@ -0,0 +1,7 @@
1
+ # # Load Spec Helper
2
+ # require File.join(File.expand_path(File.dirname(__FILE__)), 'spec_helper')
3
+ #
4
+ # describe StackFu::ApiHooks do
5
+ # describe Script do
6
+ # end
7
+ # end
@@ -0,0 +1,65 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe StackFu::Commands::DeployCommand do
5
+ it "presents the options when none given" do
6
+ command "deploy"
7
+ stdout.should =~ /You have to tell which script you want to deploy and to which server./
8
+ end
9
+
10
+ it "deploys a server" do
11
+ prepare(:get, '/servers/webbynode.json')
12
+ prepare(:get, '/scripts/firewall.json')
13
+ prepare(:post, '/servers/webbynode/deploy.json')
14
+
15
+ when_asked " Ports: ", :answer => "80,23,22"
16
+
17
+ agree_with "Continue with script installation?\n"
18
+
19
+ command "deploy firewall webbynode"
20
+
21
+ stdout.should =~ /Preparing: firewall/
22
+ stdout.should =~ /Set up a firewall for your server to improve security./
23
+ end
24
+
25
+ it "shows an error when the script is not found" do
26
+ prepare(:get, '/scripts/my_script.json', '/scripts/not_found.json')
27
+
28
+ command "deploy my_script server"
29
+ stdout.should =~ /Script 'my_script' was not found/
30
+ end
31
+
32
+ it "shows an error when script found but server not found" do
33
+ prepare(:get, '/scripts/firewall.json', '/scripts/firewall.json')
34
+ prepare(:get, '/servers/slicey.json', '/servers/not_found.json')
35
+
36
+ command "deploy firewall slicey"
37
+ stdout.should =~ /Server 'slicey' was not found/
38
+ end
39
+
40
+ it "tells the user if there's a problem submitting the deployment" do
41
+ prepare(:get, '/scripts/firewall.json')
42
+ prepare(:get, '/servers/webbynode.json')
43
+ prepare_raise(:post, '/servers/webbynode/deploy.json', Errno::ECONNREFUSED)
44
+
45
+ when_asked " Ports: ", :answer => "20,21,22"
46
+
47
+ agree_with "Continue with script installation?\n"
48
+
49
+ command "deploy firewall webbynode"
50
+ stdout.should =~ /Could not connect to StackFu server./
51
+ end
52
+
53
+ it "stops deploying if user disagree of continue prompt" do
54
+ prepare(:get, '/scripts/firewall.json')
55
+ prepare(:get, '/servers/webbynode.json')
56
+
57
+ when_asked " Ports: ", :answer => "20,21,22"
58
+
59
+ disagree_of "Continue with script installation?\n"
60
+
61
+ command "deploy firewall webbynode"
62
+ stdout.should =~ /Aborted./
63
+ end
64
+
65
+ end
@@ -0,0 +1,47 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe StackFu::Commands::DumpCommand do
5
+ it "requires a parameter" do
6
+ command "dump"
7
+ stdout.should =~ /You have to tell which script you want to dump/
8
+ end
9
+
10
+ it "displays an error when the stack is not found" do
11
+ prepare :get, "/scripts/my_script.json", "/scripts/not_found.json"
12
+ command "dump my_script"
13
+ stdout.should =~ /Script 'my_script' was not found/
14
+ end
15
+
16
+ it "asks before overwriting an existing folder" do
17
+ prepare :get, "/scripts/firewall.json", "/scripts/firewall.json"
18
+
19
+ StackFu::Commands::DumpCommand.any_instance.expects(:directory?).with("firewall").returns(true)
20
+ disagree_of("There is already a folder called 'firewall'. Do you want to overwrite its contents?")
21
+
22
+ command "dump firewall"
23
+ stdout.should =~ /Aborted./
24
+ end
25
+
26
+ context "valid script" do
27
+ it "creates a directory structure that describes the stack" do
28
+ prepare :get, "/scripts/firewall.json", "/scripts/firewall.json"
29
+
30
+ StackFu::Commands::DumpCommand.any_instance.expects(:directory?).with("firewall").returns(false)
31
+
32
+ command "dump firewall"
33
+ stdout.should =~ /^\tcreate firewall\//
34
+ stdout.should =~ /^\tcreate firewall\/script.yml/
35
+ stdout.should =~ /^\tcreate firewall\/config\//
36
+ stdout.should =~ /^\tcreate firewall\/config\/01-controls.yml/
37
+ stdout.should =~ /^\tcreate firewall\/config\/02-requirements.yml/
38
+ stdout.should =~ /^\tcreate firewall\/config\/03-executions.yml/
39
+ stdout.should =~ /^\tcreate firewall\/config\/04-validations.yml/
40
+ stdout.should =~ /^\tcreate firewall\/executables\//
41
+ stdout.should =~ /^\tcreate firewall\/executables\//
42
+ stdout.should =~ /^\tcreate firewall\/executables\/install_ufw.sh.erb/
43
+ stdout.should =~ /^\tcreate firewall\/executables\/configure_ufw.sh.erb/
44
+ stdout.should =~ /^Script firewall dumped successfully/
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,90 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe StackFu::Commands::GenerateCommand do
5
+ it "generates the script file and folder when no executables are given" do
6
+ expect_create :dir => "test", :file => "script.yml"
7
+ expect_create :dir => "test/executables"
8
+ expect_create :dir => "test/config", :file => "01-controls.yml"
9
+ expect_create :dir => "test/config", :file => "02-requirements.yml"
10
+ expect_create :dir => "test/config", :file => "03-executions.yml"
11
+ expect_create :dir => "test/config", :file => "04-validations.yml"
12
+
13
+ command "generate test"
14
+ stdout.should =~ /Script test created successfully/
15
+ end
16
+
17
+ it "generates proper tree with one executable passed" do
18
+ expect_create :dir => "other", :file => "script.yml"
19
+ expect_create :dir => "other/executables", :file => "install_counter_strike_server.sh.erb"
20
+ expect_create :dir => "other/config", :file => "01-controls.yml"
21
+ expect_create :dir => "other/config", :file => "02-requirements.yml"
22
+ expect_create :dir => "other/config", :file => "03-executions.yml",
23
+ :contents => [/install_counter_strike_server/, /Install Counter Strike Server/]
24
+ expect_create :dir => "other/config", :file => "04-validations.yml"
25
+
26
+ command "generate other install_counter_strike_server:script"
27
+ stdout.should =~ /Script other created successfully/
28
+ end
29
+
30
+ it "generates proper tree with scripts and controls" do
31
+ expect_create :dir => "test", :file => "script.yml"
32
+ expect_create :dir => "test/executables", :file => "install_counter_strike_server.sh.erb"
33
+ expect_create :dir => "test/executables", :file => "show_me_the_money.sh.erb"
34
+ expect_create :dir => "test/config", :file => "01-controls.yml",
35
+ :contents => [
36
+ /name: clan_name/, /label: Clan Name/, /type: Textbox/,
37
+ /name: clan_password/, /label: Clan Password/, /type: Password/
38
+ ]
39
+ expect_create :dir => "test/config", :file => "02-requirements.yml"
40
+ expect_create :dir => "test/config", :file => "03-executions.yml",
41
+ :contents => [
42
+ /install_counter_strike_server/, /Install Counter Strike Server/,
43
+ /show_me_the_money/, /Show Me The Money/
44
+ ]
45
+ expect_create :dir => "test/config", :file => "04-validations.yml"
46
+
47
+ command "generate test clan_name:textbox clan_password:password install_counter_strike_server:script show_me_the_money:script"
48
+ end
49
+
50
+ it "raises an error message if one of the params is unknown" do
51
+ command "generate test abcdef"
52
+ stdout.should =~ /Don't know how to generate a script with abcdef. Use 'stackfu help generate' for more information./
53
+ end
54
+
55
+ it "raises an error message if one of the params is of invalid type" do
56
+ command "generate test yogurt:food"
57
+ stdout.should =~ /Don't know how to generate a script with food yogurt. Use 'stackfu help generate' for more information./
58
+ end
59
+
60
+ it "raises a nice error when mkdir fails" do
61
+ expect_create :dir => "test", :file => "script.yml", :raise => [IOError, "Error description"]
62
+ command "generate test"
63
+ stdout.should =~ /There was an error creating your script: Error description/
64
+ end
65
+
66
+ it "raises a nice error when mkdir fails because there is a file with same name" do
67
+ expect_create :dir => "test", :file => "script.yml", :raise => [Errno::EEXIST, "Error description"]
68
+ command "generate test"
69
+ stdout.should =~ /There was an error creating your script: File exists - Error description/
70
+ end
71
+
72
+ def expect_create(opts={})
73
+ expect = StackFu::Commands::GenerateCommand.any_instance.expects(:create).with do |dir, file, contents|
74
+ dir_match = opts[:dir] ? dir == opts[:dir] : true
75
+ file_match = opts[:file] ? file == opts[:file] : true
76
+ contents_match = opts[:contents] ?
77
+ opts[:contents].each do |c|
78
+ break true if contents =~ c
79
+ false
80
+ end : true
81
+ block_match = block_given? ? yield(dir, file, contents) : true
82
+
83
+ its_a_match = dir_match and file_match and contents_match and block_match
84
+ end
85
+
86
+ if opts[:raise]
87
+ expect.raises(opts[:raise].first, opts[:raise].last)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,53 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe StackFu::Commands::ListCommand do
5
+ it "tells the user if no scripts were found" do
6
+ prepare(:get, '/scripts.json', 'scripts/none.json')
7
+ prepare(:get, '/servers.json', 'servers/none.json')
8
+ command "list"
9
+
10
+ stdout.should =~ /You have nothing to list yet. To generate a new script, use the 'stackfu generate' command/
11
+ end
12
+
13
+ it "lists scripts" do
14
+ prepare(:get, '/scripts.json', 'scripts/all.json')
15
+ prepare(:get, '/servers.json', 'servers/none.json')
16
+ command "list scripts"
17
+
18
+ stdout.should =~ /Listing 4 scripts/
19
+ stdout.should =~ /firewall/
20
+ stdout.should =~ /mongodb/
21
+ stdout.should =~ /memcached/
22
+ stdout.should =~ /mysql/
23
+ end
24
+
25
+ it "lists servers" do
26
+ prepare(:get, '/scripts.json', 'scripts/none.json')
27
+ prepare(:get, '/servers.json', 'servers/all.json')
28
+ command "list servers"
29
+
30
+ stdout.should =~ /Listing 2 servers/
31
+ stdout.should =~ /Webbynode/
32
+ stdout.should =~ /MyDog/
33
+ end
34
+
35
+ it "lists both" do
36
+ prepare(:get, '/servers.json', 'servers/all.json')
37
+ prepare(:get, '/scripts.json', 'scripts/all.json')
38
+
39
+ command "list"
40
+
41
+ stdout.should =~ /Listing 4 scripts/
42
+ stdout.should =~ /firewall/
43
+ stdout.should =~ /mongodb/
44
+ stdout.should =~ /memcached/
45
+ stdout.should =~ /mysql/
46
+
47
+ stdout.should =~ /Listing 2 servers/
48
+ stdout.should =~ /Webbynode/
49
+ stdout.should =~ /MyDog/
50
+ stdout.should =~ /123.45.678.90/
51
+ stdout.should =~ /123.45.678.91/
52
+ end
53
+ end
@@ -0,0 +1,67 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe StackFu::Commands::PublishCommand do
5
+
6
+ it "checks if script exists before publishing" do
7
+ prepare(:get, '/scripts/firewall.json', '/scripts/firewall.json')
8
+ prepare(:delete, '/scripts/firewall.json', '/scripts/delete.json')
9
+ prepare(:post, '/scripts.json', '/scripts/create.json')
10
+
11
+ setup_script(:script_name => 'firewall')
12
+
13
+ agree_with("You already have a script named firewall. Do you want to update it?")
14
+
15
+ command "pub"
16
+ stdout.should =~ /Publishing script firewall/
17
+ stdout.should =~ /Success/
18
+ end
19
+
20
+ def setup_script(options={})
21
+ StackFu::Commands::PublishCommand.any_instance.expects(:read).with("script.yml").returns(<<-EOS)
22
+ ---
23
+ type: stack
24
+ name: #{options[:"script_name"] || "my_script"}
25
+ description: "This will deploy my script"
26
+ EOS
27
+ StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/01-controls.yml").returns(<<-EOS)
28
+ controls:
29
+ - name: nome
30
+ label: Nome
31
+ type: Textbox
32
+ - name: idade
33
+ label: Idade
34
+ type: Numericbox
35
+ EOS
36
+ StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/02-requirements.yml").returns(<<-EOS)
37
+ requirements:
38
+
39
+ - type: directory
40
+ data: "/var"
41
+ error: "You need /var folder before installing"
42
+ EOS
43
+ StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/03-executions.yml").returns(options[:scripts] || <<-EOS)
44
+ executions:
45
+
46
+ - description: Echoer
47
+ file: echoer
48
+ EOS
49
+ StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/04-validations.yml").returns(<<-EOS)
50
+ validations:
51
+ - type: directory
52
+ data: "/etc/apache2"
53
+ error: Apache was not installed properly
54
+ EOS
55
+
56
+ unless options[:scripts]
57
+ StackFu::Commands::PublishCommand.any_instance.expects(:read).with("executables/echoer.sh.erb").returns(<<-EOS)
58
+ #
59
+ # echoe.sh
60
+ # Echoes a variable
61
+ #
62
+
63
+ echo "<%= nome %> is <%= age %> years old"
64
+ EOS
65
+ end
66
+ end
67
+ 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.1"
5
+ s.version = "0.1.2.1"
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-08-29}
9
+ s.date = %q{2010-09-07}
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
- 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/helpers/providers_credentials.rb", "lib/stackfu/helpers/rendering.rb", "lib/stackfu/operating_systems.rb"]
15
- s.files = ["CHANGELOG", "Manifest", "README", "README.md", "Rakefile", "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/helpers/providers_credentials.rb", "lib/stackfu/helpers/rendering.rb", "lib/stackfu/operating_systems.rb", "stackfu-installer/config/01-controls.yml", "stackfu-installer/config/02-requirements.yml", "stackfu-installer/config/03-scripts.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", "stackfu.gemspec", "templates/01-controls.yml.erb", "templates/02-requirements.yml.erb", "templates/03-scripts.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/stack.yml", "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"]
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/03-scripts.yml", "firewall/config/04-validations.yml", "firewall/executables/configure_ufw.sh.erb", "firewall/executables/install_ufw.sh.erb", "firewall/script.yml", "firewall/script/configure_ufw.sh.erb", "firewall/script/install_ufw.sh.erb", "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/scripts/all.json", "spec/fixtures/scripts/create.json", "spec/fixtures/scripts/delete.json", "spec/fixtures/scripts/firewall.json", "spec/fixtures/scripts/none.json", "spec/fixtures/scripts/not_found.json", "spec/fixtures/scripts/script_not_found.json", "spec/fixtures/servers/all.json", "spec/fixtures/servers/cannot_deploy.json", "spec/fixtures/servers/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", "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 --==--