puppet-validator 0.0.9 → 0.1.0
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.
- checksums.yaml +5 -13
- data/README.md +39 -104
- data/bin/puppet-validator +38 -1
- data/config.ru +0 -2
- data/lib/puppet-validator.rb +181 -136
- data/lib/puppet-validator/helpers.rb +40 -0
- data/lib/puppet-validator/validators.rb +5 -0
- data/lib/puppet-validator/validators/lint.rb +46 -0
- data/lib/puppet-validator/validators/rspec.rb +90 -0
- data/lib/puppet-validator/validators/syntax.rb +96 -0
- data/public/font-awesome-4.7.0/css/font-awesome.css +2337 -0
- data/public/font-awesome-4.7.0/css/font-awesome.min.css +4 -0
- data/public/font-awesome-4.7.0/fonts/FontAwesome.otf +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.eot +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.svg +2671 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.woff +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/scripts.js +203 -35
- data/public/styles.css +85 -54
- data/public/validation.js +95 -0
- data/views/index.erb +29 -7
- data/views/result.erb +23 -27
- metadata +33 -43
- data/bin/grapher +0 -44
- data/public/info.png +0 -0
- data/public/prism-default.css +0 -227
- data/public/prism.js +0 -961
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YmUxZGMwYmM3ZGE3MjI0ZjNmZDUxMDdlMDYyYTZjOWExNDg3MzUzMA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 42c7dd8c42d525d1d2b73688beeb01b3595477a1
|
4
|
+
data.tar.gz: d121433916a22680ae5692e59ece41a8f60c9eb4
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MmYyNzkwZGY3MjU5MmExYjExNDA0ZjZkODk2ZjdlMTJmYzYxMzBjNTY4ZDll
|
11
|
-
MWZiNTBlMWMxYTRjZjRjYzc4YWZlY2U4NGNiZTk5MmM0YWEzY2U=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
M2E0NGIwZDQ3NzZmNzliOTE2N2QyMWFjNDYyZWFmY2VlNzU3NjBhYzRiMDIx
|
14
|
-
N2E4ZmRmYzJiYWY0OTc4ZjA2OGVlNzBkYWEzYjY2MWY1NGZlM2RmNGY0NDFh
|
15
|
-
YmVkMWEwYjNmYzdiYmY3ZjBkYTBmNTNkMTk1MmI1NjU4NGQ0YmY=
|
6
|
+
metadata.gz: d8a6b17cef56ab2112e0414d97cfc31e501dc64c6fa9a5f358417cedc0be2ea47b8bcc9ba951367b6aa67c083af72d9ab659c557b2b0ec2645ae5545f02d62cc
|
7
|
+
data.tar.gz: 077da604c15b3beb0cde4513b63f9e01cd4eef89c5b42f91e0135f1f2e582d13f30cbf1a8f1fbdd0fbf2078dfde51eaa97e78b099a26cef3f8471ed0a6cec471
|
data/README.md
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# Puppet Validator:
|
2
2
|
## Puppet Code Validation as a service
|
3
3
|
|
4
|
-
Puppet Validator is a simple web service that accepts arbitrary code submissions
|
5
|
-
validates it the way `puppet parser validate` would.
|
6
|
-
|
4
|
+
Puppet Validator is a simple web service that accepts arbitrary code submissions
|
5
|
+
and validates it the way `puppet parser validate` and `puppet-lint` would. For
|
6
|
+
simple and self-contained manifests, it can also show you a relationship graph.
|
7
7
|
|
8
8
|
Puppet Validator is completely themeable, albeit rather primitively.
|
9
9
|
|
10
|
+
See an example running on https://validate.puppet.com
|
11
|
+
|
10
12
|
### Usage:
|
11
13
|
|
12
14
|
#### Running the service directly
|
@@ -22,25 +24,33 @@ and will serve content directly out of its installation directory. You can
|
|
22
24
|
override and customize the web content by passing the `-t` or `--theme`
|
23
25
|
command-line argument. See [Creating your own theme](#creating-your-own-theme) below.
|
24
26
|
|
27
|
+
This can load code from several popular paste services and can gist validated
|
28
|
+
code to https://gist.github.com. These gists include a `referer` link back so
|
29
|
+
the gisted code can be re-validated at any time. If you'd like the `referer`
|
30
|
+
check to work properly, make sure to run this with a valid SSL certificate.
|
31
|
+
|
25
32
|
Options:
|
26
33
|
|
27
34
|
-d, --debug Display or log debugging messages
|
28
|
-
|
29
|
-
|
35
|
+
--disable DISABLED_CHECKS Lint checks to disable. Either comma-separated list or filename.
|
36
|
+
-l, --logfile [LOGFILE] Path to logfile. Defaults to no logging, or /var/log/puppet-validator if no filename is passed.
|
30
37
|
-p, --port PORT Port to listen on. Defaults to 9000.
|
31
38
|
-t, --theme THEMEDIR Path to the theme directory.
|
32
|
-
-x, --csrf Protect from cross site request forgery. Requires code to be
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
39
|
+
-x, --csrf Protect from cross site request forgery. Requires code to be submitted for validation via the webpage.
|
40
|
+
-g, --graph Generate relationship graphs from validated code. Requires `graphviz` to be installed.
|
41
|
+
--ssl Run with SSL support. Autogenerates a self-signed certificates by default.
|
42
|
+
--ssl-cert FILE Specify the SSL certificate you'd like use use. Pair with --ssl-key.
|
43
|
+
--ssl-key FILE Specify the SSL key file you'd like use use. Pair with --ssl-cert.
|
44
|
+
|
37
45
|
-h, --help Displays this help
|
38
46
|
|
47
|
+
|
39
48
|
#### Integrating with Middleware
|
40
49
|
|
41
50
|
If you plan to run this as a public service, then you may want to run it under
|
42
|
-
middleware
|
43
|
-
specific implementation will depend on your choice of webserver
|
51
|
+
middleware (such as Phusion Passenger, Puma, or Unicorn) for performance and
|
52
|
+
scalability. The specific implementation will depend on your choice of webserver
|
53
|
+
and middleware.
|
44
54
|
|
45
55
|
To configure Puppet Validator on Apache and Passenger, you'll need to
|
46
56
|
<a href="https://www.phusionpassenger.com/library/install/apache/install/oss/el7/">
|
@@ -81,7 +91,6 @@ require 'puppet-validator'
|
|
81
91
|
logger = Logger.new('/var/log/puppet-validator')
|
82
92
|
logger.level = Logger::WARN
|
83
93
|
|
84
|
-
PuppetValidator.set :puppet_versions, Dir.glob('*').select {|f| File.symlink? f and File.readlink(f) == '.' }
|
85
94
|
PuppetValidator.set :root, File.dirname(__FILE__)
|
86
95
|
PuppetValidator.set :logger, logger
|
87
96
|
|
@@ -93,7 +102,6 @@ PuppetValidator.set :disabled_lint_checks, ['80chars']
|
|
93
102
|
# Protect from cross site request forgery. With this set, code may be
|
94
103
|
# submitted for validation by the website only.
|
95
104
|
#
|
96
|
-
# Note: This will currently break multiple version validation.
|
97
105
|
PuppetValidator.set :csrf, false
|
98
106
|
|
99
107
|
# Provide the option to generate relationship graphs from validated code.
|
@@ -114,17 +122,19 @@ command *will overwrite* existing files, but it will warn you before it does so.
|
|
114
122
|
root@master:~ # cd /etc/puppet-validator/
|
115
123
|
root@master:/etc/puppet-validator # puppet-validator init
|
116
124
|
Initializing directory as new Puppet Validator theme...
|
117
|
-
root@master:/etc/puppet-validator # tree
|
125
|
+
root@master:/etc/puppet-validator # tree -L 2
|
118
126
|
.
|
119
127
|
├── LICENSE
|
120
128
|
├── README.md
|
121
129
|
├── config.ru
|
122
130
|
├── public
|
123
|
-
│ ├──
|
124
|
-
│ ├──
|
125
|
-
│ ├──
|
131
|
+
│ ├── font-awesome-4.7.0
|
132
|
+
│ ├── gist.png
|
133
|
+
│ ├── relationships.html
|
134
|
+
│ ├── scripts.js
|
126
135
|
│ ├── styles.css
|
127
|
-
│
|
136
|
+
│ ├── testing.html
|
137
|
+
│ └── validation.js
|
128
138
|
└── views
|
129
139
|
├── index.erb
|
130
140
|
└── result.erb
|
@@ -132,7 +142,7 @@ command *will overwrite* existing files, but it will warn you before it does so.
|
|
132
142
|
Once you've created your theme, you can start the Puppet Validator service using the `-t`
|
133
143
|
or `--theme` command line arguments to tell Puppet Validator where to find your content.
|
134
144
|
|
135
|
-
root@master:~ # puppet-validator
|
145
|
+
root@master:~ # puppet-validator --theme /etc/puppet-validator/
|
136
146
|
|
137
147
|
Alternatively, you can edit your webserver virtual host configuration to point
|
138
148
|
to the *public* directory within your new theme, as in the example shown above.
|
@@ -171,93 +181,18 @@ PuppetValidator.set :disabled_lint_checks, '/etc/puppet-validator/disabled_check
|
|
171
181
|
|
172
182
|
#### Validating code against multiple Puppet versions
|
173
183
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
versions in different `Location` blocks since version 4.0 by loading separate
|
178
|
-
threads for each.
|
179
|
-
|
180
|
-
We can take advantage of that by configuring multiple Ruby environments using `rvm`
|
181
|
-
or `rbenv` and installing different gemsets. A simple Puppet module to do this
|
182
|
-
is included in the repository, with the caveat that it was designed to fully own
|
183
|
-
a single-purpose VM and has so far only been tested on CentOS 7.
|
184
|
-
|
185
|
-
If configuring manually, you'll need to create a gemset for each Puppet version
|
186
|
-
you want to validate, with something like the following.
|
187
|
-
|
188
|
-
root@master:~ # rvm install ruby-1.9.3-p551
|
189
|
-
Searching for binary rubies, this might take some time.
|
190
|
-
[...]
|
191
|
-
root@master:~ # rvm use 1.9
|
192
|
-
Using /usr/local/rvm/gems/ruby-1.9.3-p551
|
193
|
-
root@master:~ # rvm gemset create puppet2.7.4
|
194
|
-
ruby-1.9.3-p551 - #gemset created /usr/local/rvm/gems/ruby-1.9.3-p551@puppet2.7.4
|
195
|
-
ruby-1.9.3-p551 - #generating puppet2.7.4 wrappers........
|
196
|
-
root@master:~ # rvm gemset use puppet2.7.4
|
197
|
-
Using ruby-1.9.3-p551 with gemset puppet2.7.4
|
198
|
-
root@master:~ # gem install puppet -v 2.7.4
|
199
|
-
[...]
|
200
|
-
root@master:~ # gem install puppet-validator
|
201
|
-
[...]
|
202
|
-
root@master:~ # passenger-config --ruby-command
|
203
|
-
passenger-config was invoked through the following Ruby interpreter:
|
204
|
-
Command: /usr/local/rvm/gems/ruby-1.9.3-p551@puppet2.7.4/wrappers/ruby
|
205
|
-
Version: ruby 1.9.3p551 (2014-11-13 revision 48407) [x86_64-linux]
|
206
|
-
To use in Apache: PassengerRuby /usr/local/rvm/gems/ruby-1.9.3-p551@puppet2.7.4/wrappers/ruby
|
207
|
-
To use in Nginx : passenger_ruby /usr/local/rvm/gems/ruby-1.9.3-p551@puppet2.7.4/wrappers/ruby
|
208
|
-
To use with Standalone: /usr/local/rvm/gems/ruby-1.9.3-p551@puppet2.7.4/wrappers/ruby /usr/bin/passenger start
|
209
|
-
|
210
|
-
|
211
|
-
## Notes for RVM users
|
212
|
-
Do you want to know which command to use for a different Ruby interpreter? 'rvm use' that Ruby interpreter, then re-run 'passenger-config about ruby-command'.
|
213
|
-
|
214
|
-
Make a note of the `PassengerRuby` command for each gemset. You'll use it in the next step.
|
215
|
-
|
216
|
-
You will need a `Location` block in your Apache `VirtualHost` for each versioned
|
217
|
-
Puppet gemset you created above. The example file below shows blocks for three
|
218
|
-
Puppet versions with the current version installed into the default directory.
|
219
|
-
|
220
|
-
``` Apache
|
221
|
-
<VirtualHost *:80>
|
222
|
-
ServerName vhost.example.com
|
223
|
-
DocumentRoot "/var/www/puppet-validator/public"
|
224
|
-
|
225
|
-
# The default root will validate against the current Puppet version
|
226
|
-
<Directory "/var/www/puppet-validator/public">
|
227
|
-
Options -MultiViews
|
228
|
-
AllowOverride All
|
229
|
-
Require all granted
|
230
|
-
</Directory>
|
231
|
-
|
232
|
-
Alias /2.7.4 /var/www/puppet-validator/2.7.4/public
|
233
|
-
<Location /2.7.4>
|
234
|
-
PassengerBaseURI /2.7.4
|
235
|
-
PassengerAppRoot /var/www/puppet-validator/2.7.4
|
236
|
-
PassengerRuby "/usr/local/rvm/gems/ruby-1.9.3-p551@puppet2.7.4/wrappers/ruby"
|
237
|
-
</Location>
|
238
|
-
|
239
|
-
Alias /3.6.2 /var/www/puppet-validator/3.6.2/public
|
240
|
-
<Location /3.6.2>
|
241
|
-
PassengerBaseURI /3.6.2
|
242
|
-
PassengerAppRoot /var/www/puppet-validator/3.6.2
|
243
|
-
PassengerRuby "/usr/local/rvm/gems/ruby-1.9.3-p551@puppet3.6.2/wrappers/ruby"
|
244
|
-
</Location>
|
245
|
-
|
246
|
-
## Logging
|
247
|
-
ErrorLog "/var/log/httpd/vhost.example.com_error.log"
|
248
|
-
ServerSignature Off
|
249
|
-
CustomLog "/var/log/httpd/vhost.example.com_access.log" combined
|
250
|
-
</VirtualHost>
|
251
|
-
```
|
184
|
+
Puppet Validator runs a new process to validate each submission. This means that
|
185
|
+
it can lazy-load the requested Puppet version on demand. Simply `gem install` all
|
186
|
+
the versions you want and they'll be visible in the drop-down selector.
|
252
187
|
|
253
|
-
|
254
|
-
|
188
|
+
# Installing a specific version
|
189
|
+
root@master:~ # gem install puppet -v 5.3.3
|
255
190
|
|
256
|
-
|
257
|
-
root@master:~ #
|
258
|
-
root@master:~ # ln -s . 3.6.2
|
191
|
+
# Installing several versions at once
|
192
|
+
root@master:~ # gem install puppet:3.8.8 puppet:4.10.0 puppet:5.3.3
|
259
193
|
|
260
|
-
|
194
|
+
If you use the `puppet_validator` module, simply specify the versions you want
|
195
|
+
as an array,
|
261
196
|
|
262
197
|
#### Running standalone with `systemd`
|
263
198
|
|
data/bin/puppet-validator
CHANGED
@@ -12,9 +12,11 @@ options = {
|
|
12
12
|
:root => gemroot,
|
13
13
|
:csrf => false,
|
14
14
|
:graph => false,
|
15
|
+
:spec => '/var/puppet-validator/spec'
|
15
16
|
}
|
16
17
|
logfile = $stderr
|
17
18
|
loglevel = Logger::WARN
|
19
|
+
ssl_opts = {:verify_peer => false}
|
18
20
|
|
19
21
|
optparse = OptionParser.new { |opts|
|
20
22
|
opts.banner = "Usage : puppet-validator [-p <port>] [-l [logfile]] [-t <themedir>] [-d]
|
@@ -47,6 +49,10 @@ optparse = OptionParser.new { |opts|
|
|
47
49
|
options[:root] = arg
|
48
50
|
end
|
49
51
|
|
52
|
+
opts.on("-s SPECDIR", "--spec SPECDIR", "Path to the directory where spec tests are located.") do |arg|
|
53
|
+
options[:spec] = arg
|
54
|
+
end
|
55
|
+
|
50
56
|
opts.on("-x", "--csrf", "Protect from cross site request forgery. Requires code to be submitted for validation via the webpage.") do
|
51
57
|
options[:csrf] = true
|
52
58
|
end
|
@@ -55,6 +61,18 @@ optparse = OptionParser.new { |opts|
|
|
55
61
|
options[:graph] = true
|
56
62
|
end
|
57
63
|
|
64
|
+
opts.on("--ssl", "Run with SSL support. Autogenerates a self-signed certificates by default.") do
|
65
|
+
options[:ssl] = true
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.on("--ssl-cert FILE", "Specify the SSL certificate you'd like use use. Pair with --ssl-key.") do |arg|
|
69
|
+
ssl_opts[:cert_chain_file] = arg
|
70
|
+
end
|
71
|
+
|
72
|
+
opts.on("--ssl-key FILE", "Specify the SSL key file you'd like use use. Pair with --ssl-cert.") do |arg|
|
73
|
+
ssl_opts[:private_key_file] = arg
|
74
|
+
end
|
75
|
+
|
58
76
|
opts.separator('')
|
59
77
|
|
60
78
|
opts.on("-h", "--help", "Displays this help") do
|
@@ -84,5 +102,24 @@ else
|
|
84
102
|
logger.level = loglevel
|
85
103
|
options[:logger] = logger
|
86
104
|
|
87
|
-
|
105
|
+
if ssl_opts[:cert_chain_file] and ssl_opts[:private_key_file]
|
106
|
+
options[:ssl] = true
|
107
|
+
end
|
108
|
+
|
109
|
+
# These options should either both be nil or both be Strings
|
110
|
+
unless ssl_opts[:cert_chain_file].class == ssl_opts[:private_key_file].class
|
111
|
+
raise 'You must specify both the certificate and key file!'
|
112
|
+
end
|
113
|
+
|
114
|
+
PuppetValidator.run!(options) do |server|
|
115
|
+
if options[:ssl]
|
116
|
+
if server.respond_to? 'ssl='
|
117
|
+
logger.info 'Enabling SSL support.'
|
118
|
+
server.ssl = true
|
119
|
+
server.ssl_options = ssl_opts
|
120
|
+
else
|
121
|
+
logger.warn "Please 'gem install thin' or run via an app server for SSL support."
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
88
125
|
end
|
data/config.ru
CHANGED
@@ -4,7 +4,6 @@ require 'puppet-validator'
|
|
4
4
|
logger = Logger.new('/var/log/puppet-validator')
|
5
5
|
logger.level = Logger::WARN
|
6
6
|
|
7
|
-
PuppetValidator.set :puppet_versions, Dir.glob('*').select {|f| File.symlink? f and File.readlink(f) == '.' }
|
8
7
|
PuppetValidator.set :root, File.dirname(__FILE__)
|
9
8
|
PuppetValidator.set :logger, logger
|
10
9
|
|
@@ -16,7 +15,6 @@ PuppetValidator.set :disabled_lint_checks, ['80chars']
|
|
16
15
|
# Protect from cross site request forgery. With this set, code may be
|
17
16
|
# submitted for validation by the website only.
|
18
17
|
#
|
19
|
-
# Note: This will currently break multiple version validation.
|
20
18
|
PuppetValidator.set :csrf, false
|
21
19
|
|
22
20
|
# Provide the option to generate relationship graphs from validated code.
|
data/lib/puppet-validator.rb
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'logger'
|
3
3
|
require 'sinatra/base'
|
4
|
-
require 'puppet'
|
5
|
-
require 'puppet/parser'
|
6
|
-
require 'puppet-lint'
|
7
|
-
|
8
|
-
require 'graphviz'
|
9
4
|
require 'nokogiri'
|
10
5
|
require 'cgi'
|
6
|
+
require 'uri'
|
7
|
+
require 'open-uri'
|
11
8
|
|
12
|
-
# something like 3,000 lines of code
|
13
|
-
|
14
|
-
CONTEXT = 3
|
9
|
+
MAXSIZE = 100000 # something like 3,000 lines of code
|
10
|
+
CONTEXT = 3 # how many lines of code around an error should we highlight?
|
15
11
|
|
16
12
|
class PuppetValidator < Sinatra::Base
|
13
|
+
require 'puppet-validator/validators'
|
14
|
+
require 'puppet-validator/helpers'
|
15
|
+
|
17
16
|
set :logging, true
|
18
17
|
set :strict, true
|
19
18
|
|
@@ -25,6 +24,7 @@ class PuppetValidator < Sinatra::Base
|
|
25
24
|
if settings.csrf
|
26
25
|
session[:csrf] ||= SecureRandom.hex(32)
|
27
26
|
response.set_cookie 'authenticity_token', {
|
27
|
+
:path => '/',
|
28
28
|
:value => session[:csrf],
|
29
29
|
:expires => Time.now + (60 * 60 * 24),
|
30
30
|
}
|
@@ -34,16 +34,6 @@ class PuppetValidator < Sinatra::Base
|
|
34
34
|
def initialize(app=nil)
|
35
35
|
super(app)
|
36
36
|
|
37
|
-
Puppet.initialize_settings rescue nil
|
38
|
-
Puppet.settings[:app_management] = true if Gem::Version.new(Puppet.version) >= Gem::Version.new('4.3.2')
|
39
|
-
|
40
|
-
# set up the base environment
|
41
|
-
Puppet.push_context(Puppet.base_context(Puppet.settings), 'Setup for Puppet Validator') rescue nil
|
42
|
-
|
43
|
-
# disable as much disk access as possible
|
44
|
-
Puppet::Node::Facts.indirection.terminus_class = :memory
|
45
|
-
Puppet::Node.indirection.cache_class = nil
|
46
|
-
|
47
37
|
# make sure that all the settings we expect are defined.
|
48
38
|
[:disabled_lint_checks, :puppet_versions, :csrf].each do |name|
|
49
39
|
next if settings.respond_to? name
|
@@ -68,175 +58,230 @@ class PuppetValidator < Sinatra::Base
|
|
68
58
|
end
|
69
59
|
end
|
70
60
|
|
71
|
-
# put
|
72
|
-
settings.puppet_versions = settings.puppet_versions.sort_by { |v| Gem::Version.new(v) }.reverse
|
61
|
+
# put all installed Puppet versions in reverse semver order
|
62
|
+
#settings.puppet_versions = settings.puppet_versions.sort_by { |v| Gem::Version.new(v) }.reverse
|
63
|
+
settings.puppet_versions = Gem::Specification.all.select {|g| g.name == 'puppet' }.collect {|g| g.version.to_s }
|
64
|
+
|
65
|
+
settings.logger.error "Please gem install one or more Puppet versions." if settings.puppet_versions.empty?
|
73
66
|
|
74
67
|
end
|
75
68
|
|
76
69
|
get '/' do
|
77
|
-
@versions =
|
70
|
+
@versions = settings.puppet_versions
|
71
|
+
@disabled = settings.disabled_lint_checks
|
72
|
+
# loads lint into global namespace, but I don't see an alternative
|
73
|
+
@checks = PuppetValidator::Validators::Lint.all_checks
|
74
|
+
|
75
|
+
erb :index
|
76
|
+
end
|
77
|
+
|
78
|
+
get '/load/referer' do
|
79
|
+
redirect "/load/#{request.referer}"
|
80
|
+
end
|
81
|
+
|
82
|
+
get '/load/*' do
|
83
|
+
location = params[:splat].first.sub(/(https?:)\/\/?/, '\1//')
|
84
|
+
logger.info "Loading code from: #{location}"
|
85
|
+
|
86
|
+
uri = location.downcase.start_with?('http') ? URI.parse(location) : URI.parse("https://#{location}")
|
87
|
+
|
88
|
+
case uri.host
|
89
|
+
when 'gist.github.com'
|
90
|
+
path = uri.path.end_with?('/raw') ? uri : "#{uri}/raw"
|
91
|
+
|
92
|
+
when 'pastebin.com', 'hastebin.com'
|
93
|
+
path = uri.path.start_with?('/raw') ? uri : "#{uri.scheme}://#{uri.host}/raw#{uri.path}"
|
94
|
+
|
95
|
+
else
|
96
|
+
path = nil
|
97
|
+
logger.info "Unrecognized paste service: #{uri}"
|
98
|
+
end
|
99
|
+
|
100
|
+
@versions = settings.puppet_versions
|
78
101
|
@disabled = settings.disabled_lint_checks
|
79
|
-
|
102
|
+
# loads lint into global namespace, but I don't see an alternative
|
103
|
+
@checks = PuppetValidator::Validators::Lint.all_checks
|
104
|
+
@location = location
|
105
|
+
|
106
|
+
if path
|
107
|
+
@code = sanitize_code(open(path).read) rescue nil
|
108
|
+
end
|
80
109
|
|
81
110
|
erb :index
|
82
111
|
end
|
83
112
|
|
113
|
+
# The all-in-one blob that renders via an erb page
|
84
114
|
post '/validate' do
|
85
115
|
logger.info "Validating code from #{request.ip}."
|
86
116
|
logger.debug "validating #{request.ip}: #{params['code']}"
|
87
117
|
|
88
|
-
|
89
|
-
|
90
|
-
frag = Nokogiri::HTML.fragment(params['code'])
|
91
|
-
unless frag.elements.empty?
|
92
|
-
logger.warn 'HTML code found in validation string'
|
93
|
-
frag.elements.each { |elem| logger.debug "HTML: #{elem.to_s}" }
|
94
|
-
params['code'] = CGI.escapeHTML(params['code'])
|
118
|
+
if params.include? 'load'
|
119
|
+
redirect "/load/#{params['location']}"
|
95
120
|
end
|
96
121
|
|
97
|
-
|
98
|
-
|
99
|
-
lint = lint(params['code'], params['checks']) if params['lint'] == 'on'
|
100
|
-
lint ||= {} # but make sure we have a data object to iterate
|
122
|
+
validate_request!
|
123
|
+
sanitize_code! # make code safe for re-rendering
|
101
124
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
@column = result[:pos]
|
108
|
-
@lint_warnings = ! lint.empty?
|
125
|
+
PuppetValidator.run_in_process do
|
126
|
+
if params.include? 'relationships' and settings.graph
|
127
|
+
syntax = PuppetValidator::Validators::Syntax.new(settings)
|
128
|
+
results = syntax.validate(params['code'])
|
129
|
+
results[:status] ? syntax.render! : results[:message]
|
109
130
|
|
110
|
-
# initial highlighting for the potential syntax error
|
111
|
-
if @line
|
112
|
-
start = [@line - CONTEXT, 1].max
|
113
|
-
initial = {"#{start}-#{@line}" => nil}
|
114
131
|
else
|
115
|
-
|
132
|
+
@result = validate_all
|
133
|
+
@result[:code] = params['code']
|
134
|
+
|
135
|
+
erb :result
|
116
136
|
end
|
137
|
+
end
|
138
|
+
end
|
117
139
|
|
118
|
-
|
119
|
-
@highlights = lint.inject(initial) do |acc, item|
|
120
|
-
acc.merge({item[:line] => "#{item[:kind].upcase}: #{item[:message]}"})
|
121
|
-
end.to_json
|
140
|
+
################### API v0 endpoints ###################
|
122
141
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
142
|
+
post '/api/v0/validate' do
|
143
|
+
validate_request!
|
144
|
+
|
145
|
+
PuppetValidator.run_in_process do
|
146
|
+
validate_all.to_json
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
post '/api/v0/validate/syntax' do
|
151
|
+
validate_request!
|
152
|
+
|
153
|
+
PuppetValidator.run_in_process do
|
154
|
+
syntax = PuppetValidator::Validators::Syntax.new(settings)
|
155
|
+
syntax.validate(params['code']).to_json
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
post '/api/v0/validate/relationships' do
|
160
|
+
validate_request!
|
161
|
+
halt 403, 'Graph generation disabled.' unless settings.graph
|
162
|
+
|
163
|
+
PuppetValidator.run_in_process do
|
164
|
+
syntax = PuppetValidator::Validators::Syntax.new(settings)
|
165
|
+
|
166
|
+
# need to prebuild the catalog first
|
167
|
+
results = syntax.validate(params['code'])
|
168
|
+
# return either an SVG or the error message
|
169
|
+
results[:status] ? syntax.render! : results[:message]
|
128
170
|
end
|
129
171
|
|
130
|
-
erb :result
|
131
172
|
end
|
132
173
|
|
174
|
+
post '/api/v0/validate/lint' do
|
175
|
+
validate_request!
|
176
|
+
|
177
|
+
PuppetValidator.run_in_process do
|
178
|
+
linter = PuppetValidator::Validators::Lint.new(settings)
|
179
|
+
linter.validate(params['code']).to_json
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
post '/api/v0/validate/rspec' do
|
184
|
+
validate_request!
|
185
|
+
|
186
|
+
PuppetValidator.run_in_process do
|
187
|
+
rspec = PuppetValidator::Validators::Rspec.new(settings)
|
188
|
+
rspec.validate(params['code'], params['spec']).to_json
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
#######################################################
|
193
|
+
|
133
194
|
not_found do
|
134
195
|
halt 404, "You shall not pass! (page not found)\n"
|
135
196
|
end
|
136
197
|
|
137
198
|
helpers do
|
138
199
|
|
139
|
-
def
|
200
|
+
def validate_request!
|
201
|
+
csrf_safe!
|
202
|
+
check_size_limit!
|
203
|
+
end
|
204
|
+
|
205
|
+
def csrf_safe!
|
140
206
|
return true unless settings.csrf
|
141
207
|
if session[:csrf] == params['_csrf'] && session[:csrf] == request.cookies['authenticity_token']
|
142
208
|
true
|
143
209
|
else
|
144
|
-
logger.warn 'CSRF attempt detected.'
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
def validate(data)
|
150
|
-
begin
|
151
|
-
Puppet[:code] = data
|
152
|
-
|
153
|
-
if Puppet::Node::Environment.respond_to?(:create)
|
154
|
-
validation_environment = Puppet::Node::Environment.create(:production, [])
|
155
|
-
validation_environment.check_for_reparse
|
156
|
-
else
|
157
|
-
validation_environment = Puppet::Node::Environment.new(:production)
|
158
|
-
end
|
159
|
-
|
160
|
-
validation_environment.known_resource_types.clear
|
210
|
+
logger.warn 'CSRF attempt detected. Ensure that server time is correct.'
|
211
|
+
logger.debug "session: #{session[:csrf]}"
|
212
|
+
logger.debug " param: #{params['_csrf']}"
|
213
|
+
logger.debug " cookie: #{request.cookies['authenticity_token']}"
|
161
214
|
|
162
|
-
|
163
|
-
rescue => detail
|
164
|
-
logger.warn detail.message
|
165
|
-
err = {:status => false, :message => detail.message}
|
166
|
-
err[:line] = detail.line if detail.methods.include? :line
|
167
|
-
err[:pos] = detail.pos if detail.methods.include? :pos
|
168
|
-
err
|
215
|
+
halt 403, 'Request validation failed.'
|
169
216
|
end
|
170
217
|
end
|
171
218
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
175
|
-
logger.info "Disabling checks: #{(puppet_lint_checks - checks).inspect}"
|
176
|
-
|
177
|
-
checks.each do |check|
|
178
|
-
PuppetLint.configuration.send("enable_#{check}")
|
179
|
-
end
|
180
|
-
|
181
|
-
(puppet_lint_checks - checks).each do |check|
|
182
|
-
PuppetLint.configuration.send("disable_#{check}")
|
183
|
-
end
|
184
|
-
else
|
185
|
-
logger.info "Disabling checks: #{settings.disabled_lint_checks.inspect}"
|
186
|
-
|
187
|
-
settings.disabled_lint_checks.each do |check|
|
188
|
-
PuppetLint.configuration.send("disable_#{check}")
|
189
|
-
end
|
190
|
-
end
|
219
|
+
def check_size_limit!
|
220
|
+
content = request.body.read
|
221
|
+
request.body.rewind
|
191
222
|
|
192
|
-
|
193
|
-
|
194
|
-
linter.run
|
195
|
-
linter.print_problems
|
196
|
-
rescue => detail
|
197
|
-
logger.warn detail.message
|
198
|
-
nil
|
223
|
+
if content.size > MAXSIZE
|
224
|
+
halt 403, "Submitted code size is #{content.size}, which is larger than the maximum size of #{MAXSIZE}."
|
199
225
|
end
|
200
226
|
end
|
201
227
|
|
202
|
-
def
|
203
|
-
|
204
|
-
PuppetLint.configuration.checks.map {|check| check.to_s}
|
228
|
+
def sanitize_code!
|
229
|
+
params['code'] = sanitize_code(params['code'])
|
205
230
|
end
|
206
231
|
|
207
|
-
def
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
catalog.remove_resource(catalog.resource("Stage", :main)) rescue nil
|
217
|
-
catalog.remove_resource(catalog.resource("Class", :settings)) rescue nil
|
232
|
+
def sanitize_code(code)
|
233
|
+
frag = Nokogiri::HTML.fragment(code)
|
234
|
+
unless frag.elements.empty?
|
235
|
+
logger.warn 'HTML code found in validation string'
|
236
|
+
frag.elements.each { |elem| logger.debug "HTML: #{elem.to_s}" }
|
237
|
+
code = CGI.escapeHTML(code)
|
238
|
+
end
|
239
|
+
code
|
240
|
+
end
|
218
241
|
|
219
|
-
|
242
|
+
def validate_all
|
243
|
+
syntax = PuppetValidator::Validators::Syntax.new(settings, params['version'])
|
244
|
+
result = syntax.validate(params['code'])
|
220
245
|
|
221
|
-
|
222
|
-
|
246
|
+
# munge the data slightly to make it more consumable
|
247
|
+
result[:version] = params['version']
|
248
|
+
result[:success] = result[:status]
|
249
|
+
result[:status] = result[:status] ? :success : :fail
|
250
|
+
result[:column] = result[:pos]
|
251
|
+
result[:messages] = []
|
223
252
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
253
|
+
# initial highlighting for the potential syntax error
|
254
|
+
if result[:line]
|
255
|
+
line = result[:line]
|
256
|
+
start = [line - CONTEXT, 0].max
|
257
|
+
|
258
|
+
result[:messages] << {
|
259
|
+
:from => [start, 0],
|
260
|
+
:to => [line - 1, result[:column]],
|
261
|
+
:message => result[:message],
|
262
|
+
:severity => 'error',
|
263
|
+
}
|
264
|
+
end
|
232
265
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
266
|
+
# then add all the lint warnings and tooltip
|
267
|
+
if params['lint']
|
268
|
+
linter = PuppetValidator::Validators::Lint.new(settings)
|
269
|
+
lint = linter.validate(params['code'], params['checks'])
|
270
|
+
|
271
|
+
result[:lint_warnings] = ! lint.empty?
|
272
|
+
|
273
|
+
lint.each do |item|
|
274
|
+
line = item[:line]-1;
|
275
|
+
result[:messages] << {
|
276
|
+
:from => [line, 0],
|
277
|
+
:to => [line, 1000],
|
278
|
+
:message => "#{item[:kind].upcase}: #{item[:message]}",
|
279
|
+
:severity => 'warning'
|
280
|
+
}
|
281
|
+
end
|
237
282
|
end
|
238
283
|
|
239
|
-
|
284
|
+
result
|
240
285
|
end
|
241
286
|
|
242
287
|
end
|