chef-server-webui 0.8.16 → 0.9.0.a3
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 +14 -10
- data/app/controllers/application.rb +111 -128
- data/app/controllers/clients.rb +10 -10
- data/app/controllers/cookbook_attributes.rb +1 -1
- data/app/controllers/cookbook_definitions.rb +1 -1
- data/app/controllers/cookbook_files.rb +1 -1
- data/app/controllers/cookbook_libraries.rb +1 -1
- data/app/controllers/cookbook_recipes.rb +1 -1
- data/app/controllers/cookbook_templates.rb +1 -1
- data/app/controllers/cookbooks.rb +21 -3
- data/app/controllers/databag_items.rb +6 -6
- data/app/controllers/databags.rb +3 -3
- data/app/controllers/main.rb +1 -1
- data/app/controllers/nodes.rb +21 -21
- data/app/controllers/openid_consumer.rb +9 -9
- data/app/controllers/roles.rb +3 -3
- data/app/controllers/search.rb +1 -1
- data/app/controllers/search_entries.rb +1 -1
- data/app/controllers/status.rb +1 -1
- data/app/controllers/users.rb +7 -7
- data/app/helpers/application_helper.rb +1 -156
- data/app/helpers/global_helpers.rb +20 -16
- data/app/helpers/nodes_helper.rb +24 -22
- data/app/helpers/openid_server_helpers.rb +13 -10
- data/app/helpers/search_helper.rb +44 -38
- data/app/helpers/status_helper.rb +10 -3
- data/app/views/clients/_navigation.html.haml +5 -5
- data/app/views/clients/edit.html.haml +1 -1
- data/app/views/clients/index.html.haml +4 -4
- data/app/views/clients/new.html.haml +1 -1
- data/app/views/cookbooks/index.html.haml +1 -1
- data/app/views/cookbooks/show.html.haml +25 -16
- data/app/views/databag_items/_form.html.haml +1 -1
- data/app/views/databag_items/_navigation.html.haml +5 -5
- data/app/views/databag_items/edit.html.haml +1 -1
- data/app/views/databag_items/new.html.haml +1 -1
- data/app/views/databags/_item_navigation.html.haml +4 -4
- data/app/views/databags/_navigation.html.haml +5 -5
- data/app/views/databags/edit.html.haml +1 -1
- data/app/views/databags/index.html.haml +3 -3
- data/app/views/databags/new.html.haml +1 -1
- data/app/views/databags/show.html.haml +3 -3
- data/app/views/layout/{chef_server_webui.html.haml → application.html.haml} +11 -11
- data/app/views/layout/login.html.haml +1 -1
- data/app/views/nodes/_form.html.haml +1 -1
- data/app/views/nodes/_navigation.html.haml +5 -5
- data/app/views/nodes/edit.html.haml +1 -1
- data/app/views/nodes/index.html.haml +6 -6
- data/app/views/nodes/new.html.haml +1 -1
- data/app/views/nodes/show.html.haml +4 -5
- data/app/views/openid_consumer/index.html.haml +2 -2
- data/app/views/openid_register/index.html.haml +4 -4
- data/app/views/openid_register/show.html.haml +1 -1
- data/app/views/roles/_form.html.haml +1 -1
- data/app/views/roles/_navigation.html.haml +5 -5
- data/app/views/roles/edit.html.haml +1 -1
- data/app/views/roles/index.html.haml +4 -4
- data/app/views/roles/new.html.haml +1 -1
- data/app/views/roles/show.html.haml +3 -4
- data/app/views/search/_search_form.html.haml +1 -1
- data/app/views/search/index.html.haml +1 -1
- data/app/views/search/show.html.haml +1 -1
- data/app/views/status/index.html.haml +9 -12
- data/app/views/users/_form.html.haml +1 -1
- data/app/views/users/_navigation.html.haml +5 -5
- data/app/views/users/edit.html.haml +1 -1
- data/app/views/users/index.html.haml +3 -3
- data/app/views/users/login.html.haml +1 -1
- data/app/views/users/new.html.haml +1 -1
- data/bin/chef-server-webui +72 -0
- data/config.ru +10 -74
- data/config/init.rb +30 -11
- data/config/rack.rb +5 -0
- data/config/router.rb +62 -5
- data/lib/chef-server-webui.rb +2 -155
- data/lib/chef-server-webui/version.rb +3 -0
- data/public/javascripts/drop_down_menu.js +22 -0
- metadata +60 -48
- data/stubs/app/controllers/application.rb +0 -2
- data/stubs/app/controllers/main.rb +0 -2
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/lib/chef-server-webui/version'
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'rake/gempackagetask'
|
3
5
|
|
@@ -5,7 +7,6 @@ require 'merb-core'
|
|
5
7
|
require 'merb-core/tasks/merb'
|
6
8
|
|
7
9
|
GEM_NAME = "chef-server-webui"
|
8
|
-
CHEF_SERVER_VERSION="0.8.16"
|
9
10
|
AUTHOR = "Opscode"
|
10
11
|
EMAIL = "chef@opscode.com"
|
11
12
|
HOMEPAGE = "http://wiki.opscode.com/display/chef"
|
@@ -13,7 +14,7 @@ SUMMARY = "A systems integration framework, built to bring the benefits of confi
|
|
13
14
|
|
14
15
|
spec = Gem::Specification.new do |s|
|
15
16
|
s.name = GEM_NAME
|
16
|
-
s.version =
|
17
|
+
s.version = ChefServerWebui::VERSION
|
17
18
|
s.platform = Gem::Platform::RUBY
|
18
19
|
s.has_rdoc = true
|
19
20
|
s.extra_rdoc_files = ["README.rdoc", "LICENSE" ]
|
@@ -23,17 +24,20 @@ spec = Gem::Specification.new do |s|
|
|
23
24
|
s.email = EMAIL
|
24
25
|
s.homepage = HOMEPAGE
|
25
26
|
|
26
|
-
s.add_dependency "merb-core", "~> 1.0
|
27
|
-
s.add_dependency "merb-slices", "~> 1.0
|
28
|
-
s.add_dependency "merb-assets", "~> 1.0
|
29
|
-
s.add_dependency "merb-helpers", "~> 1.0
|
30
|
-
s.add_dependency "merb-haml", "~> 1.0
|
31
|
-
s.add_dependency "merb-param-protection", "~> 1.0
|
27
|
+
s.add_dependency "merb-core", "~> 1.0"
|
28
|
+
s.add_dependency "merb-slices", "~> 1.0"
|
29
|
+
s.add_dependency "merb-assets", "~> 1.0"
|
30
|
+
s.add_dependency "merb-helpers", "~> 1.0"
|
31
|
+
s.add_dependency "merb-haml", "~> 1.0"
|
32
|
+
s.add_dependency "merb-param-protection", "~> 1.0"
|
32
33
|
|
33
34
|
s.add_dependency "json", "<= 1.4.2"
|
34
35
|
|
35
36
|
%w{thin haml ruby-openid coderay}.each { |g| s.add_dependency g}
|
36
37
|
|
38
|
+
s.bindir = "bin"
|
39
|
+
s.executables = %w( chef-server-webui )
|
40
|
+
|
37
41
|
s.require_path = 'lib'
|
38
42
|
s.files = %w(LICENSE README.rdoc Rakefile config.ru) + Dir.glob("{bin,config,lib,spec,app,public,stubs}/**/*")
|
39
43
|
end
|
@@ -44,12 +48,12 @@ end
|
|
44
48
|
|
45
49
|
desc "Install the gem"
|
46
50
|
task :install => :package do
|
47
|
-
sh %{gem install pkg/#{GEM_NAME}-#{
|
51
|
+
sh %{gem install pkg/#{GEM_NAME}-#{ChefServerWebui::VERSION} --no-rdoc --no-ri}
|
48
52
|
end
|
49
53
|
|
50
54
|
desc "Uninstall the gem"
|
51
55
|
task :uninstall do
|
52
|
-
sh %{gem uninstall #{GEM_NAME} -x -v #{
|
56
|
+
sh %{gem uninstall #{GEM_NAME} -x -v #{ChefServerWebui::VERSION} }
|
53
57
|
end
|
54
58
|
|
55
59
|
desc "Create a gemspec file"
|
@@ -8,9 +8,9 @@
|
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
9
|
# you may not use this file except in compliance with the License.
|
10
10
|
# You may obtain a copy of the License at
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# Unless required by applicable law or agreed to in writing, software
|
15
15
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
16
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -21,67 +21,42 @@
|
|
21
21
|
require "chef" / "mixin" / "checksum"
|
22
22
|
require "chef" / "cookbook_loader"
|
23
23
|
|
24
|
-
class
|
24
|
+
class Application < Merb::Controller
|
25
25
|
|
26
26
|
include Chef::Mixin::Checksum
|
27
27
|
|
28
|
-
controller_for_slice
|
29
|
-
|
30
|
-
# Generate the absolute url for a slice - takes the slice's :path_prefix into account.
|
31
|
-
#
|
32
|
-
# @param slice_name<Symbol>
|
33
|
-
# The name of the slice - in identifier_sym format (underscored).
|
34
|
-
# @param *args<Array[Symbol,Hash]>
|
35
|
-
# There are several possibilities regarding arguments:
|
36
|
-
# - when passing a Hash only, the :default route of the current
|
37
|
-
# slice will be used
|
38
|
-
# - when a Symbol is passed, it's used as the route name
|
39
|
-
# - a Hash with additional params can optionally be passed
|
40
|
-
#
|
41
|
-
# @return <String> A uri based on the requested slice.
|
42
|
-
#
|
43
|
-
# @example absolute_slice_url(:awesome, :format => 'html')
|
44
|
-
# @example absolute_slice_url(:forum, :posts, :format => 'xml')
|
45
|
-
def absolute_slice_url(slice_name, *args)
|
46
|
-
options = extract_options_from_args!(args) || {}
|
47
|
-
protocol = options.delete(:protocol) || request.protocol
|
48
|
-
host = options.delete(:host) || request.host
|
49
|
-
|
50
|
-
protocol + "://" + host + slice_url(slice_name,*args)
|
51
|
-
end
|
52
|
-
|
53
28
|
# Check if the user is logged in and if the user still exists
|
54
29
|
def login_required
|
55
30
|
if session[:user]
|
56
31
|
begin
|
57
32
|
Chef::WebUIUser.load(session[:user]) rescue (raise NotFound, "Cannot find User #{session[:user]}, maybe it got deleted by an Administrator.")
|
58
|
-
rescue
|
33
|
+
rescue
|
59
34
|
logout_and_redirect_to_login
|
60
|
-
else
|
35
|
+
else
|
61
36
|
return session[:user]
|
62
|
-
end
|
63
|
-
else
|
37
|
+
end
|
38
|
+
else
|
64
39
|
self.store_location
|
65
40
|
throw(:halt, :access_denied)
|
66
41
|
end
|
67
42
|
end
|
68
|
-
|
43
|
+
|
69
44
|
def cleanup_session
|
70
45
|
[:user,:level].each { |n| session.delete(n) }
|
71
|
-
end
|
72
|
-
|
46
|
+
end
|
47
|
+
|
73
48
|
def logout_and_redirect_to_login
|
74
49
|
cleanup_session
|
75
50
|
@user = Chef::WebUIUser.new
|
76
|
-
redirect(
|
77
|
-
end
|
78
|
-
|
79
|
-
|
51
|
+
redirect(url(:users_login), {:message => { :error => $! }, :permanent => true})
|
52
|
+
end
|
53
|
+
|
54
|
+
|
80
55
|
def is_admin(name)
|
81
56
|
user = Chef::WebUIUser.load(name)
|
82
57
|
return user.admin
|
83
58
|
end
|
84
|
-
|
59
|
+
|
85
60
|
#return true if there is only one admin left, false otehrwise
|
86
61
|
def is_last_admin
|
87
62
|
count = 0
|
@@ -95,32 +70,12 @@ class ChefServerWebui::Application < Merb::Controller
|
|
95
70
|
end
|
96
71
|
true
|
97
72
|
end
|
98
|
-
|
73
|
+
|
99
74
|
#whether or not the user should be able to edit a user's admin status
|
100
75
|
def edit_admin
|
101
76
|
is_admin(params[:user_id]) ? (!is_last_admin) : true
|
102
|
-
end
|
103
|
-
|
104
|
-
def authorized_node
|
105
|
-
# if session[:level] == :admin
|
106
|
-
# Chef::Log.debug("Authorized as Administrator")
|
107
|
-
# true
|
108
|
-
# elsif session[:level] == :node
|
109
|
-
# Chef::Log.debug("Authorized as node")
|
110
|
-
# if session[:node_name] == params[:id].gsub(/\./, '_')
|
111
|
-
# true
|
112
|
-
# else
|
113
|
-
# raise(
|
114
|
-
# Unauthorized,
|
115
|
-
# "You are not the correct node for this action: #{session[:node_name]} instead of #{params[:id]}"
|
116
|
-
# )
|
117
|
-
# end
|
118
|
-
# else
|
119
|
-
# Chef::Log.debug("Unauthorized")
|
120
|
-
# raise Unauthorized, "You are not allowed to take this action."
|
121
|
-
# end
|
122
77
|
end
|
123
|
-
|
78
|
+
|
124
79
|
def authorized_user
|
125
80
|
if session[:level] == :admin
|
126
81
|
Chef::Log.debug("Authorized as Administrator")
|
@@ -128,9 +83,9 @@ class ChefServerWebui::Application < Merb::Controller
|
|
128
83
|
else
|
129
84
|
Chef::Log.debug("Unauthorized")
|
130
85
|
raise Unauthorized, "The current user is not an Administrator, you can only Show and Edit the user itself. To control other users, login as an Administrator."
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
134
89
|
# Store the URI of the current request in the session.
|
135
90
|
#
|
136
91
|
# We can return to this location by calling #redirect_back_or_default.
|
@@ -145,18 +100,18 @@ class ChefServerWebui::Application < Merb::Controller
|
|
145
100
|
session[:return_to] = nil
|
146
101
|
redirect loc
|
147
102
|
end
|
148
|
-
|
103
|
+
|
149
104
|
def access_denied
|
150
105
|
case content_type
|
151
106
|
when :html
|
152
107
|
store_location
|
153
|
-
redirect
|
108
|
+
redirect url(:users_login), :message => { :error => "You don't have access to that, please login."}
|
154
109
|
else
|
155
110
|
raise Unauthorized, "You must authenticate first!"
|
156
111
|
end
|
157
112
|
end
|
158
|
-
|
159
|
-
# Load a cookbook and return a hash with a list of all the files of a
|
113
|
+
|
114
|
+
# Load a cookbook and return a hash with a list of all the files of a
|
160
115
|
# given segment (attributes, recipes, definitions, libraries)
|
161
116
|
#
|
162
117
|
# === Parameters
|
@@ -166,14 +121,14 @@ class ChefServerWebui::Application < Merb::Controller
|
|
166
121
|
# === Returns
|
167
122
|
# <Hash>:: A hash consisting of the short name of the file in :name, and the full path
|
168
123
|
# to the file in :file.
|
169
|
-
def load_cookbook_segment(cookbook_id, segment)
|
124
|
+
def load_cookbook_segment(cookbook_id, segment)
|
170
125
|
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
171
126
|
cookbook = r.get_rest("cookbooks/#{cookbook_id}")
|
172
127
|
|
173
128
|
raise NotFound unless cookbook
|
174
|
-
|
129
|
+
|
175
130
|
files_list = segment_files(segment, cookbook)
|
176
|
-
|
131
|
+
|
177
132
|
files = Hash.new
|
178
133
|
files_list.each do |f|
|
179
134
|
files[f['name']] = {
|
@@ -183,7 +138,7 @@ class ChefServerWebui::Application < Merb::Controller
|
|
183
138
|
end
|
184
139
|
files
|
185
140
|
end
|
186
|
-
|
141
|
+
|
187
142
|
def segment_files(segment, cookbook)
|
188
143
|
files_list = nil
|
189
144
|
case segment
|
@@ -201,59 +156,87 @@ class ChefServerWebui::Application < Merb::Controller
|
|
201
156
|
files_list
|
202
157
|
end
|
203
158
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
159
|
+
def build_tree(name, node)
|
160
|
+
html = "<table id='#{name}' class='tree table'>"
|
161
|
+
html << "<tr><th class='first'>Attribute</th><th class='last'>Value</th></tr>"
|
162
|
+
count = 0
|
163
|
+
parent = 0
|
164
|
+
append_tree(name, html, node, count, parent)
|
165
|
+
html << "</table>"
|
166
|
+
html
|
167
|
+
end
|
168
|
+
|
169
|
+
def append_tree(name, html, node, count, parent)
|
170
|
+
to_do = node
|
171
|
+
#to_do = node.kind_of?(Chef::Node) ? node.attribute : node
|
172
|
+
Chef::Log.error("I have #{to_do.inspect}")
|
173
|
+
to_do.sort{ |a,b| a[0] <=> b[0] }.each do |key, value|
|
174
|
+
Chef::Log.error("I am #{key.inspect} #{value.inspect}")
|
175
|
+
to_send = Array.new
|
176
|
+
count += 1
|
177
|
+
is_parent = false
|
178
|
+
local_html = ""
|
179
|
+
local_html << "<tr id='#{name}-#{count}' class='collapsed #{name}"
|
180
|
+
if parent != 0
|
181
|
+
local_html << " child-of-#{name}-#{parent}' style='display: none;'>"
|
182
|
+
else
|
183
|
+
local_html << "'>"
|
184
|
+
end
|
185
|
+
local_html << "<td class='table-key'><span toggle='#{name}-#{count}'/>#{key}</td>"
|
186
|
+
case value
|
187
|
+
when Hash
|
188
|
+
is_parent = true
|
189
|
+
local_html << "<td></td>"
|
190
|
+
p = count
|
191
|
+
to_send << Proc.new { append_tree(name, html, value, count, p) }
|
192
|
+
when Array
|
193
|
+
is_parent = true
|
194
|
+
local_html << "<td></td>"
|
195
|
+
as_hash = {}
|
196
|
+
value.each_index { |i| as_hash[i] = value[i] }
|
197
|
+
p = count
|
198
|
+
to_send << Proc.new { append_tree(name, html, as_hash, count, p) }
|
199
|
+
else
|
200
|
+
local_html << "<td><div class='json-attr'>#{value}</div></td>"
|
201
|
+
end
|
202
|
+
local_html << "</tr>"
|
203
|
+
local_html.sub!(/class='collapsed/, 'class=\'collapsed parent') if is_parent
|
204
|
+
local_html.sub!(/<span/, "<span class='expander'") if is_parent
|
205
|
+
html << local_html
|
206
|
+
to_send.each { |s| count = s.call }
|
207
|
+
count += to_send.length
|
208
|
+
end
|
209
|
+
count
|
210
|
+
end
|
211
|
+
|
212
|
+
def syntax_highlight(code)
|
213
|
+
tokens = File.exists?(code) ? CodeRay.scan_file(code, :ruby) : CodeRay.scan(code, :ruby)
|
214
|
+
CodeRay.encode_tokens(tokens, :span)
|
215
|
+
end
|
216
|
+
|
217
|
+
def get_file(uri)
|
218
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
219
|
+
content = r.get_rest(uri)
|
220
|
+
a = Tempfile.new("cookbook_temp_file")
|
221
|
+
File.open(a.path, 'w'){|f| f.write(content)}
|
222
|
+
path = a.path
|
223
|
+
a.close
|
224
|
+
path
|
225
|
+
end
|
226
|
+
|
227
|
+
def str_to_bool(str)
|
228
|
+
str =~ /true/ ? true : false
|
229
|
+
end
|
230
|
+
|
231
|
+
#for showing search result
|
232
|
+
def determine_name(type, object)
|
233
|
+
case type
|
234
|
+
when :node, :role, :client
|
235
|
+
object.name
|
236
|
+
else
|
237
|
+
params[:id]
|
238
|
+
end
|
239
|
+
end
|
257
240
|
|
258
241
|
def get_available_recipes
|
259
242
|
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
@@ -264,7 +247,7 @@ class ChefServerWebui::Application < Merb::Controller
|
|
264
247
|
cb["recipes"].each do |recipe|
|
265
248
|
recipe["name"] =~ /(.+)\.rb/
|
266
249
|
r_name = $1;
|
267
|
-
if r_name == "default"
|
250
|
+
if r_name == "default"
|
268
251
|
result << key
|
269
252
|
else
|
270
253
|
result << "#{key}::#{r_name}"
|
@@ -273,7 +256,7 @@ class ChefServerWebui::Application < Merb::Controller
|
|
273
256
|
end
|
274
257
|
result
|
275
258
|
end
|
276
|
-
|
259
|
+
|
277
260
|
def convert_newline_to_br(string)
|
278
261
|
string.to_s.gsub(/\n/, '<br />') unless string.nil?
|
279
262
|
end
|
data/app/controllers/clients.rb
CHANGED
@@ -18,21 +18,21 @@
|
|
18
18
|
|
19
19
|
require 'chef/api_client'
|
20
20
|
|
21
|
-
class
|
21
|
+
class Clients < Application
|
22
22
|
provides :json
|
23
23
|
provides :html
|
24
24
|
before :login_required
|
25
25
|
|
26
26
|
# GET /clients
|
27
27
|
def index
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
begin
|
29
|
+
@clients_list = Chef::ApiClient.list().keys.sort
|
30
|
+
rescue => e
|
31
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
32
|
+
@_message = {:error => "Could not list clients"}
|
33
|
+
@clients_list = []
|
34
|
+
end
|
35
|
+
render
|
36
36
|
end
|
37
37
|
|
38
38
|
# GET /clients/:id
|
@@ -107,7 +107,7 @@ class ChefServerWebui::Clients < ChefServerWebui::Application
|
|
107
107
|
begin
|
108
108
|
@client = Chef::ApiClient.load(params[:id])
|
109
109
|
@client.destroy
|
110
|
-
redirect(
|
110
|
+
redirect(absolute_url(:clients), {:message => { :notice => "Client #{params[:id]} deleted successfully" }, :permanent => true})
|
111
111
|
rescue => e
|
112
112
|
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
113
113
|
@_message = {:error => "Could not delete client #{params[:id]}" }
|