stackfu 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/stackfu/commands/deploy_command.rb +19 -13
- data/lib/stackfu/commands/dump_command.rb +4 -4
- data/lib/stackfu/commands/generate_command.rb +13 -5
- data/lib/stackfu/commands/help_command.rb +5 -5
- data/lib/stackfu/commands/publish_command.rb +111 -1
- data/lib/stackfu.rb +1 -1
- data/spec/spec_helper.rb +4 -0
- data/spec/stackfu/commands/deploy_command_spec.rb +15 -0
- data/spec/stackfu/commands/dump_command_spec.rb +1 -1
- data/spec/stackfu/commands/generate_command_spec.rb +7 -2
- data/spec/stackfu/commands/publish_command_spec.rb +299 -9
- data/stackfu.gemspec +2 -2
- metadata +4 -4
data/Rakefile
CHANGED
@@ -18,21 +18,27 @@ module StackFu::Commands
|
|
18
18
|
|
19
19
|
def extract_settings(target)
|
20
20
|
target_name = parameters[0]
|
21
|
-
server_name = parameters[1]
|
21
|
+
server_name = parameters[1]
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
if target_name.include?('/')
|
24
|
+
user_name, target_name = target_name.split('/')
|
25
|
+
user = User.new(:id => user_name)
|
26
|
+
target = Script.new(user.get(target_name))
|
27
|
+
else
|
28
|
+
begin
|
29
|
+
target_class = StackFu::ApiHooks.const_get(target.capitalize)
|
30
|
+
target = target_class.find(target_name)
|
31
|
+
rescue ActiveResource::ResourceNotFound
|
32
|
+
error "#{target.capitalize} '#{target_name}' was not found"
|
33
|
+
return
|
34
|
+
end
|
30
35
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
+
begin
|
37
|
+
target = target_class.find(target_name)
|
38
|
+
rescue ActiveResource::ResourceNotFound
|
39
|
+
error "#{target.capitalize} '#{target_name}' was not found"
|
40
|
+
return
|
41
|
+
end
|
36
42
|
end
|
37
43
|
|
38
44
|
unless target
|
@@ -82,9 +82,9 @@ module StackFu::Commands
|
|
82
82
|
create_file "#{script_name}/executables/#{script.description.downcase.gsub(" ", "_")}.sh.erb", script.body
|
83
83
|
end
|
84
84
|
|
85
|
-
|
85
|
+
done "Script #{script_name} dumped."
|
86
86
|
else
|
87
|
-
|
87
|
+
error "Script '#{script_name}' was not found"
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -99,7 +99,7 @@ module StackFu::Commands
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def create_folder(folder)
|
102
|
-
puts "\
|
102
|
+
puts "\t#{"create".foreground(:green)} #{folder}/"
|
103
103
|
mkdir folder
|
104
104
|
end
|
105
105
|
|
@@ -110,7 +110,7 @@ module StackFu::Commands
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def create_file(file, contents)
|
113
|
-
puts "\
|
113
|
+
puts "\t#{"create".foreground(:green)} #{file}"
|
114
114
|
write_file(file, contents)
|
115
115
|
end
|
116
116
|
|
@@ -31,6 +31,14 @@ module StackFu::Commands
|
|
31
31
|
what = 'script'
|
32
32
|
begin
|
33
33
|
item_name = parameters.shift
|
34
|
+
|
35
|
+
unless item_name
|
36
|
+
error "Missing script name.",
|
37
|
+
"Try again using 'stackfu generate [script_name]'."
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
|
34
42
|
items = {}
|
35
43
|
while (p = parameters.shift)
|
36
44
|
name, type = p.split(":")
|
@@ -72,11 +80,11 @@ module StackFu::Commands
|
|
72
80
|
create("#{item_name}/executables", "#{item.first}.sh.erb", item.last)
|
73
81
|
end or create("#{item_name}/executables")
|
74
82
|
|
75
|
-
|
83
|
+
done "#{what.titleize} #{item_name} created successfully"
|
76
84
|
rescue Exceptions::InvalidParameter
|
77
|
-
|
85
|
+
error $!.message
|
78
86
|
rescue IOError, Errno::EEXIST
|
79
|
-
|
87
|
+
error "#{$!.message}"
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
@@ -89,13 +97,13 @@ module StackFu::Commands
|
|
89
97
|
|
90
98
|
def create(d, f=nil, contents=nil)
|
91
99
|
unless File.directory?(d)
|
92
|
-
puts "\
|
100
|
+
puts "\t#{"create".foreground(:green)} #{d}/"
|
93
101
|
::FileUtils.mkdir_p(d)
|
94
102
|
end
|
95
103
|
|
96
104
|
if f.present?
|
97
105
|
f = "#{d}/#{f}"
|
98
|
-
puts "\
|
106
|
+
puts "\t#{"create".foreground(:green)} #{f}"
|
99
107
|
File.open(f, "w") do |file|
|
100
108
|
file.write(contents)
|
101
109
|
end
|
@@ -3,22 +3,22 @@ module StackFu::Commands
|
|
3
3
|
def default(parameters, options)
|
4
4
|
stackfu = "stackfu".foreground(:green).bright
|
5
5
|
|
6
|
-
puts "#{"StackFu #{StackFu::VERSION}".foreground(:green).bright}
|
7
|
-
puts " (c)
|
6
|
+
puts "#{"StackFu #{StackFu::VERSION}".foreground(:green).bright} - social server provisioning."
|
7
|
+
puts " (c) 2010-2020 StackFu - http://stackfu.com"
|
8
8
|
puts ""
|
9
9
|
puts " Usage:"
|
10
10
|
puts " #{stackfu} #{"command".foreground(:cyan)} [arguments...] [options...]"
|
11
11
|
puts ""
|
12
12
|
puts " Examples:"
|
13
|
-
puts " #{stackfu} #{"generate".foreground(:cyan)}
|
13
|
+
puts " #{stackfu} #{"generate".foreground(:cyan)} lamp"
|
14
14
|
puts " #{stackfu} #{"pub".foreground(:cyan)}"
|
15
15
|
puts " #{stackfu} #{"deploy".foreground(:cyan)} lamp server1"
|
16
16
|
puts ""
|
17
17
|
puts " Commands:"
|
18
18
|
puts " #{"help".foreground(:cyan)} you already know about this one, dontcha?"
|
19
19
|
puts " #{"config".foreground(:cyan)} configure StackFu CLI options"
|
20
|
-
puts " #{"
|
21
|
-
puts " #{"generate".foreground(:cyan)}
|
20
|
+
puts " #{"list".foreground(:cyan)} [servers|script] lists all the scripts and/or server under your account"
|
21
|
+
puts " #{"generate".foreground(:cyan)} creates a new script in current_dir/name"
|
22
22
|
puts " #{"publish".foreground(:cyan)} publishes the item on the current folder to StackFu.com"
|
23
23
|
puts ""
|
24
24
|
puts " For a complete guide on using StackFu from command line:"
|
@@ -10,6 +10,19 @@ module StackFu::Commands
|
|
10
10
|
def plugin?
|
11
11
|
File.exists?("plugin.yml")
|
12
12
|
end
|
13
|
+
|
14
|
+
def format_error
|
15
|
+
messages = ["there were validation problems with your script.", ""]
|
16
|
+
%w(script.yml config/01-controls.yml config/02-requirements.yml config/03-executions.yml config/04-validations.yml).each do |f|
|
17
|
+
if @errors[f]
|
18
|
+
messages << "Errors in #{f.foreground(:green)}:"
|
19
|
+
messages << @errors[f].map { |e| "- #{e}" }
|
20
|
+
messages << ""
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
messages.flatten.join("\n")
|
25
|
+
end
|
13
26
|
|
14
27
|
def default(parameters, options)
|
15
28
|
what = :script
|
@@ -20,7 +33,12 @@ module StackFu::Commands
|
|
20
33
|
end
|
21
34
|
|
22
35
|
begin
|
23
|
-
stack_spec =
|
36
|
+
stack_spec = read_and_validate(what)
|
37
|
+
|
38
|
+
if @errors.keys.any?
|
39
|
+
error format_error
|
40
|
+
return
|
41
|
+
end
|
24
42
|
|
25
43
|
%w[controls requirements executions validations].each_with_index do |item, i|
|
26
44
|
if (yaml = read("config/0#{i+1}-#{item}.yml"))
|
@@ -111,7 +129,99 @@ module StackFu::Commands
|
|
111
129
|
end
|
112
130
|
|
113
131
|
private
|
132
|
+
|
133
|
+
def check(file, message)
|
134
|
+
return true if result = block_given? ? yield : false
|
135
|
+
|
136
|
+
(@errors[file]||=[]) << message.gsub(/'(.*)'/, '\1'.foreground(:blue).bright)
|
137
|
+
false
|
138
|
+
end
|
139
|
+
|
140
|
+
def read_and_check(yml)
|
141
|
+
begin
|
142
|
+
return YAML.load(read(yml))
|
143
|
+
rescue ArgumentError
|
144
|
+
(@errors[yml]||=[]) << "invalid YAML document. Parse error: #{$!.message}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def read_and_validate(what)
|
149
|
+
@errors = {}
|
150
|
+
|
151
|
+
if stack_spec = read_and_check("#{what}.yml")
|
152
|
+
if check("script.yml", "the file descriptor has the wrong format") { stack_spec.is_a?(Hash) }
|
153
|
+
if check("script.yml", "missing field #{"name".try(:foreground, :blue).try(:bright)}") { stack_spec['name'] }
|
154
|
+
check("script.yml",
|
155
|
+
"invalid value for field #{"name".try(:foreground, :blue).try(:bright)}: " +
|
156
|
+
"only lower case chars, numbers and underscores are allowed") {
|
157
|
+
|
158
|
+
stack_spec['name'] =~ /^[a-z0-9_]*$/
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
if check("script.yml", "missing field #{"type".try(:foreground, :blue).try(:bright)}") { stack_spec['type'] }
|
163
|
+
check("script.yml", "invalid value for field #{"type".try(:foreground, :blue).try(:bright)}") { stack_spec['type'] == 'script' }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
validate_controls
|
169
|
+
validate_requirements
|
170
|
+
validate_executions
|
171
|
+
validate_validations
|
172
|
+
|
173
|
+
stack_spec
|
174
|
+
end
|
175
|
+
|
176
|
+
def validate_spec(idx, name, item_id, checks)
|
177
|
+
file = "config/#{idx}-#{name}.yml"
|
178
|
+
|
179
|
+
return unless spec = read_and_check(file)
|
180
|
+
return unless check(file, "invalid format") {
|
181
|
+
spec.is_a?(Hash) && spec[name].is_a?(Array)
|
182
|
+
}
|
183
|
+
|
184
|
+
spec[name].each_with_index do |item, i|
|
185
|
+
checks.each do |check|
|
186
|
+
if item_id.nil? or check == item_id
|
187
|
+
check(file, "missing #{check} for #{name.singularize} #{i+1}") { item[check] }
|
188
|
+
else
|
189
|
+
check(file, "missing #{check} for #{name.singularize} #{item[item_id].try(:foreground, :blue).try(:bright)}") { item[check] }
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
return unless yield(item, i+1) if block_given?
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def validate_controls
|
198
|
+
validate_spec '01', 'controls', 'name', ['name', 'type'] do |item, i|
|
199
|
+
check('config/01-controls.yml', "invalid type '#{item["type"]}' for control #{item["name"].try(:foreground, :blue).try(:bright)}") {
|
200
|
+
%w(Textbox Numericbox Password).include? item['type']
|
201
|
+
}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def validate_requirements
|
206
|
+
validate_spec '02', 'requirements', nil, ['type', 'data'] do |item, i|
|
207
|
+
check("config/02-requirements.yml", "invalid type #{item["type"].try(:foreground, :blue).try(:bright)} for requirement #{i}") {
|
208
|
+
%w(DirExists FileExists ExecutableExists ProcessExists RubyCanLoad RubyGem SymlinkExists).include? item['type']
|
209
|
+
}
|
210
|
+
end
|
211
|
+
end
|
114
212
|
|
213
|
+
def validate_executions
|
214
|
+
validate_spec '03', 'executions', 'file', ['file', 'description']
|
215
|
+
end
|
216
|
+
|
217
|
+
def validate_validations
|
218
|
+
validate_spec '04', 'validations', nil, ['type', 'data'] do |item, i|
|
219
|
+
check('config/04-validations.yml', "invalid type #{item["type"].try(:foreground, :blue).try(:bright)} for validation #{i}") {
|
220
|
+
%w(DirExists FileExists ExecutableExists ProcessExists RubyCanLoad RubyGem SymlinkExists).include? item['type']
|
221
|
+
}
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
115
225
|
def publish(stack)
|
116
226
|
spinner {
|
117
227
|
stack.save
|
data/lib/stackfu.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -15,6 +15,10 @@ HighLine.track_eof = false
|
|
15
15
|
# Reads out a file from the fixtures directory
|
16
16
|
|
17
17
|
module StackFuHelpers
|
18
|
+
def fixture?(file)
|
19
|
+
File.exists?(File.join(File.dirname(__FILE__), "fixtures", file))
|
20
|
+
end
|
21
|
+
|
18
22
|
def read_fixture(file)
|
19
23
|
File.read(File.join(File.dirname(__FILE__), "fixtures", file))
|
20
24
|
end
|
@@ -17,6 +17,21 @@ describe StackFu::Commands::DeployCommand do
|
|
17
17
|
stdout.should =~ /Aborted./
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
context "deploying other user's scripts" do
|
22
|
+
it "queries for /user/script.json" do
|
23
|
+
prepare(:get, '/users/fcoury/mongodb.json')
|
24
|
+
prepare(:get, '/servers/webbynode.json')
|
25
|
+
|
26
|
+
when_asked " Ports: ", :answer => "80,23,22"
|
27
|
+
|
28
|
+
disagree_of "Continue with script installation?\n"
|
29
|
+
|
30
|
+
command "dep fcoury/mongodb webbynode"
|
31
|
+
|
32
|
+
stdout.should =~ /Aborted./
|
33
|
+
end
|
34
|
+
end
|
20
35
|
|
21
36
|
context 'rendering controls do' do
|
22
37
|
it "tells the user if there is another deployment running" do
|
@@ -41,7 +41,7 @@ describe StackFu::Commands::DumpCommand do
|
|
41
41
|
stdout.should =~ /^\tcreate firewall\/executables\//
|
42
42
|
stdout.should =~ /^\tcreate firewall\/executables\/install_ufw.sh.erb/
|
43
43
|
stdout.should =~ /^\tcreate firewall\/executables\/configure_ufw.sh.erb/
|
44
|
-
stdout.should =~ /^Script firewall dumped
|
44
|
+
stdout.should =~ /^Success: Script firewall dumped/
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -2,6 +2,11 @@
|
|
2
2
|
require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
|
3
3
|
|
4
4
|
describe StackFu::Commands::GenerateCommand do
|
5
|
+
it "shown an error if no name is given" do
|
6
|
+
command "generate"
|
7
|
+
stdout.should =~ /Missing script name./
|
8
|
+
end
|
9
|
+
|
5
10
|
it "generates the script file and folder when no executables are given" do
|
6
11
|
expect_create :dir => "test", :file => "script.yml"
|
7
12
|
expect_create :dir => "test/executables"
|
@@ -65,13 +70,13 @@ describe StackFu::Commands::GenerateCommand do
|
|
65
70
|
it "raises a nice error when mkdir fails" do
|
66
71
|
expect_create :dir => "test", :file => "script.yml", :raise => [IOError, "Error description"]
|
67
72
|
command "generate test"
|
68
|
-
stdout.should =~ /
|
73
|
+
stdout.should =~ /Error description/
|
69
74
|
end
|
70
75
|
|
71
76
|
it "raises a nice error when mkdir fails because there is a file with same name" do
|
72
77
|
expect_create :dir => "test", :file => "script.yml", :raise => [Errno::EEXIST, "Error description"]
|
73
78
|
command "generate test"
|
74
|
-
stdout.should =~ /
|
79
|
+
stdout.should =~ /File exists - Error description/
|
75
80
|
end
|
76
81
|
|
77
82
|
def expect_create(opts={})
|
@@ -2,6 +2,278 @@
|
|
2
2
|
require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
|
3
3
|
|
4
4
|
describe StackFu::Commands::PublishCommand do
|
5
|
+
|
6
|
+
context 'validating script.yml' do
|
7
|
+
it "validates the name for invalid chars" do
|
8
|
+
setup_one 'missing', 'script.yml', "name: My Fair Scripty\ntype: script"
|
9
|
+
setup_one 'missing', 'config/01-controls.yml', ''
|
10
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
11
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
12
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
13
|
+
|
14
|
+
command "pub"
|
15
|
+
stdout.should =~ /invalid value for field name: only lower case chars, numbers and underscores are allowed/
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it "checks script.yml format" do
|
20
|
+
setup_fixture('invalid')
|
21
|
+
setup_one 'missing', 'config/01-controls.yml', ''
|
22
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
23
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
24
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
25
|
+
|
26
|
+
command "pub"
|
27
|
+
stdout.should =~ /the file descriptor has the wrong format/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "checks for valid YAML file" do
|
31
|
+
setup_one 'missing', 'script.yml', 'name: myscript, type: yadda'
|
32
|
+
setup_one 'missing', 'config/01-controls.yml', ''
|
33
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
34
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
35
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
36
|
+
|
37
|
+
command "pub"
|
38
|
+
stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 21/
|
39
|
+
end
|
40
|
+
|
41
|
+
it "checks required script field 'name'" do
|
42
|
+
setup_fixture('missing')
|
43
|
+
|
44
|
+
command "pub"
|
45
|
+
stdout.should =~ /missing field name/
|
46
|
+
end
|
47
|
+
|
48
|
+
it "checks required script field 'type'" do
|
49
|
+
setup_one 'missing', 'script.yml', 'name: myscript'
|
50
|
+
setup_one 'missing', 'config/01-controls.yml', ''
|
51
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
52
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
53
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
54
|
+
|
55
|
+
command "pub"
|
56
|
+
stdout.should =~ /missing field type/
|
57
|
+
end
|
58
|
+
|
59
|
+
it "checks content of field 'type'" do
|
60
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: yadda}'
|
61
|
+
setup_one 'missing', 'config/01-controls.yml', ''
|
62
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
63
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
64
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
65
|
+
|
66
|
+
command "pub"
|
67
|
+
stdout.should =~ /invalid value for field type/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'validating 01-controls.yml' do
|
72
|
+
it "checks file format" do
|
73
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
74
|
+
setup_one 'missing', 'config/01-controls.yml', 'hey you'
|
75
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
76
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
77
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
78
|
+
|
79
|
+
command "pub"
|
80
|
+
stdout.should =~ /invalid format/
|
81
|
+
end
|
82
|
+
|
83
|
+
it "checks for invalid YML" do
|
84
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
85
|
+
setup_one 'missing', 'config/01-controls.yml', 'name: myscript, type: yadda'
|
86
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
87
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
88
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
89
|
+
|
90
|
+
command "pub"
|
91
|
+
stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 21/
|
92
|
+
end
|
93
|
+
|
94
|
+
it "checks for missing controls key" do
|
95
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
96
|
+
setup_one 'missing', 'config/01-controls.yml', 'other: [{name: control}]'
|
97
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
98
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
99
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
100
|
+
|
101
|
+
command "pub"
|
102
|
+
stdout.should =~ /invalid format/
|
103
|
+
end
|
104
|
+
|
105
|
+
it "assures that controls is an array" do
|
106
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
107
|
+
setup_one 'missing', 'config/01-controls.yml', 'other: {name: control}'
|
108
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
109
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
110
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
111
|
+
|
112
|
+
command "pub"
|
113
|
+
stdout.should =~ /invalid format/
|
114
|
+
end
|
115
|
+
|
116
|
+
it "checks for missing name" do
|
117
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
118
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: [{type: Textbox}]'
|
119
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
120
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
121
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
122
|
+
|
123
|
+
command "pub"
|
124
|
+
stdout.should =~ /missing name for control 1/
|
125
|
+
end
|
126
|
+
|
127
|
+
it "checks for missing type" do
|
128
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
129
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: [{name: control}]'
|
130
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
131
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
132
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
133
|
+
|
134
|
+
command "pub"
|
135
|
+
stdout.should =~ /missing type for control control/
|
136
|
+
end
|
137
|
+
|
138
|
+
it "checks for invalid type" do
|
139
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
140
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: [{name: control, type: RockOn}]'
|
141
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
142
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
143
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
144
|
+
|
145
|
+
command "pub"
|
146
|
+
stdout.should =~ /invalid type RockOn for control control/
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'validating 02-requirements.yml' do
|
151
|
+
it "checks file format" do
|
152
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
153
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
154
|
+
setup_one 'missing', 'config/02-requirements.yml', 'hey you'
|
155
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
156
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
157
|
+
|
158
|
+
command "pub"
|
159
|
+
stdout.should =~ /invalid format/
|
160
|
+
end
|
161
|
+
|
162
|
+
it "checks for invalid YAML" do
|
163
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
164
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
165
|
+
setup_one 'missing', 'config/02-requirements.yml', 'name: myscript, - type: yadda'
|
166
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
167
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
168
|
+
|
169
|
+
command "pub"
|
170
|
+
stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 23/
|
171
|
+
end
|
172
|
+
|
173
|
+
it "checks for missing type" do
|
174
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
175
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
176
|
+
setup_one 'missing', 'config/02-requirements.yml', "requirements:\n- {data: x, type: DirExists}\n- data: x"
|
177
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
178
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
179
|
+
|
180
|
+
command "pub"
|
181
|
+
stdout.should =~ /missing type for requirement 2/
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'validating 03-executions.yml' do
|
186
|
+
it "checks file format" do
|
187
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
188
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
189
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
190
|
+
setup_one 'missing', 'config/03-executions.yml', 'hey you'
|
191
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
192
|
+
|
193
|
+
command "pub"
|
194
|
+
stdout.should =~ /invalid format/
|
195
|
+
end
|
196
|
+
|
197
|
+
it "checks for invalid YAML" do
|
198
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
199
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
200
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
201
|
+
setup_one 'missing', 'config/03-executions.yml', 'name: myscript, - type: yadda'
|
202
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
203
|
+
|
204
|
+
command "pub"
|
205
|
+
stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 23/
|
206
|
+
end
|
207
|
+
|
208
|
+
it "checks for missing description" do
|
209
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
210
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
211
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
212
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}\n- file: execution"
|
213
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
214
|
+
|
215
|
+
command "pub"
|
216
|
+
stdout.should =~ /missing description for execution execution/
|
217
|
+
end
|
218
|
+
|
219
|
+
it "checks for missing file" do
|
220
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
221
|
+
setup_one 'missing', 'config/01-controls.yml', ''
|
222
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
223
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}\n- description: execution"
|
224
|
+
setup_one 'missing', 'config/04-validations.yml', ''
|
225
|
+
|
226
|
+
command "pub"
|
227
|
+
stdout.should =~ /missing file for execution 2/
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'validating 04-validations.yml' do
|
232
|
+
it "checks file format" do
|
233
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
234
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
235
|
+
setup_one 'missing', 'config/02-requirements.yml', ''
|
236
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
237
|
+
setup_one 'missing', 'config/04-validations.yml', 'hey you'
|
238
|
+
|
239
|
+
command "pub"
|
240
|
+
stdout.should =~ /invalid format/
|
241
|
+
end
|
242
|
+
|
243
|
+
it "checks for invalid YAML" do
|
244
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
245
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
246
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
247
|
+
setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
|
248
|
+
setup_one 'missing', 'config/04-validations.yml', 'name: myscript, - type: yadda'
|
249
|
+
|
250
|
+
command "pub"
|
251
|
+
stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 23/
|
252
|
+
end
|
253
|
+
|
254
|
+
it "checks for missing type" do
|
255
|
+
setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
|
256
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
257
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
258
|
+
setup_one 'missing', 'config/03-executions.yml', ""
|
259
|
+
setup_one 'missing', 'config/04-validations.yml', "validations:\n- {data: x, type: DirExists}\n- data: x"
|
260
|
+
|
261
|
+
command "pub"
|
262
|
+
stdout.should =~ /missing type for validation 2/
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
it "reports all errors" do
|
267
|
+
setup_one 'missing', 'script.yml', '{name: myscript}'
|
268
|
+
setup_one 'missing', 'config/01-controls.yml', 'controls: []'
|
269
|
+
setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
|
270
|
+
setup_one 'missing', 'config/03-executions.yml', ""
|
271
|
+
setup_one 'missing', 'config/04-validations.yml', "validations:\n- {data: x, type: DirExists}\n- data: x"
|
272
|
+
|
273
|
+
command "pub"
|
274
|
+
stdout.should =~ /missing field type/
|
275
|
+
stdout.should =~ /missing type for validation 2/
|
276
|
+
end
|
5
277
|
|
6
278
|
it "checks if script exists before publishing" do
|
7
279
|
prepare(:get, '/scripts/firewall.json', '/scripts/firewall.json')
|
@@ -17,14 +289,32 @@ describe StackFu::Commands::PublishCommand do
|
|
17
289
|
stdout.should =~ /Success/
|
18
290
|
end
|
19
291
|
|
292
|
+
private
|
293
|
+
|
294
|
+
def setup_fixture(script)
|
295
|
+
setup_one script, "script.yml"
|
296
|
+
setup_one script, "config/01-controls.yml"
|
297
|
+
setup_one script, "config/02-requirements.yml"
|
298
|
+
setup_one script, "config/03-executions.yml"
|
299
|
+
setup_one script, "config/04-validations.yml"
|
300
|
+
end
|
301
|
+
|
302
|
+
def setup_one(script, expect, contents=nil)
|
303
|
+
return unless fixture?("scripts/#{script}/#{expect}")
|
304
|
+
contents ||= read_fixture("scripts/#{script}/#{expect}")
|
305
|
+
|
306
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with(expect).returns(contents)
|
307
|
+
end
|
308
|
+
|
309
|
+
|
20
310
|
def setup_script(options={})
|
21
|
-
StackFu::Commands::PublishCommand.any_instance.
|
311
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("script.yml").returns(<<-EOS)
|
22
312
|
---
|
23
|
-
type:
|
313
|
+
type: script
|
24
314
|
name: #{options[:"script_name"] || "my_script"}
|
25
315
|
description: "This will deploy my script"
|
26
316
|
EOS
|
27
|
-
StackFu::Commands::PublishCommand.any_instance.
|
317
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/01-controls.yml").returns(<<-EOS)
|
28
318
|
controls:
|
29
319
|
- name: nome
|
30
320
|
label: Nome
|
@@ -33,28 +323,28 @@ controls:
|
|
33
323
|
label: Idade
|
34
324
|
type: Numericbox
|
35
325
|
EOS
|
36
|
-
StackFu::Commands::PublishCommand.any_instance.
|
326
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/02-requirements.yml").returns(<<-EOS)
|
37
327
|
requirements:
|
38
328
|
|
39
|
-
- type:
|
329
|
+
- type: DirExists
|
40
330
|
data: "/var"
|
41
331
|
error: "You need /var folder before installing"
|
42
332
|
EOS
|
43
|
-
StackFu::Commands::PublishCommand.any_instance.
|
333
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/03-executions.yml").returns(options[:scripts] || <<-EOS)
|
44
334
|
executions:
|
45
335
|
|
46
336
|
- description: Echoer
|
47
337
|
file: echoer
|
48
338
|
EOS
|
49
|
-
StackFu::Commands::PublishCommand.any_instance.
|
339
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/04-validations.yml").returns(<<-EOS)
|
50
340
|
validations:
|
51
|
-
- type:
|
341
|
+
- type: DirExists
|
52
342
|
data: "/etc/apache2"
|
53
343
|
error: Apache was not installed properly
|
54
344
|
EOS
|
55
345
|
|
56
346
|
unless options[:scripts]
|
57
|
-
StackFu::Commands::PublishCommand.any_instance.
|
347
|
+
StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("executables/echoer.sh.erb").returns(<<-EOS)
|
58
348
|
#
|
59
349
|
# echoe.sh
|
60
350
|
# Echoes a variable
|
data/stackfu.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
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.6"
|
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-16}
|
10
10
|
s.default_executable = %q{stackfu}
|
11
11
|
s.description = %q{StackFu Backend}
|
12
12
|
s.email = %q{felipe@stackfu.com}
|
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: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 6
|
10
|
+
version: 0.1.6
|
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-16 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|