stackfu 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|